Simplify parser
This commit is contained in:
parent
962a9c53b6
commit
4724041d90
@ -8,7 +8,7 @@ pub fn get_umask() -> u32 {
|
||||
umask
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum Bit {
|
||||
Suid = 0o4000,
|
||||
Sgid = 0o2000,
|
||||
|
@ -36,14 +36,13 @@ enum Who {
|
||||
User,
|
||||
Group,
|
||||
Other,
|
||||
All,
|
||||
}
|
||||
|
||||
pub struct Parser {
|
||||
mode: u32,
|
||||
op: Option<Op>,
|
||||
who: Vec<Who>,
|
||||
bits: Vec<char>,
|
||||
bits: Vec<Bit>,
|
||||
}
|
||||
|
||||
impl Default for Parser {
|
||||
@ -97,175 +96,95 @@ impl Parser {
|
||||
}
|
||||
}
|
||||
|
||||
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),
|
||||
fn push_read_bits(&mut self) -> Result<(), ParseError> {
|
||||
for w in &self.who {
|
||||
match w {
|
||||
Who::User => self.bits.push(Bit::URead),
|
||||
Who::Group => self.bits.push(Bit::GRead),
|
||||
Who::Other => self.bits.push(Bit::ORead),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn push_suid(&mut self) -> Result<(), ParseError> {
|
||||
fn push_write_bits(&mut self) -> Result<(), ParseError> {
|
||||
for w in &self.who {
|
||||
if w == &Who::All || w == &Who::Other {
|
||||
return Err(ParseError::InvalidBit);
|
||||
match w {
|
||||
Who::User => self.bits.push(Bit::UWrite),
|
||||
Who::Group => self.bits.push(Bit::GWrite),
|
||||
Who::Other => self.bits.push(Bit::OWrite),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn push_exec_bits(&mut self) -> Result<(), ParseError> {
|
||||
for w in &self.who {
|
||||
match w {
|
||||
Who::User => self.bits.push(Bit::UExec),
|
||||
Who::Group => self.bits.push(Bit::GExec),
|
||||
Who::Other => self.bits.push(Bit::OExec),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn push_suid_sgid(&mut self) -> Result<(), ParseError> {
|
||||
if self.who.is_empty() {
|
||||
return Err(ParseError::InvalidBit);
|
||||
}
|
||||
self.push_bit('s')
|
||||
for w in &self.who {
|
||||
match w {
|
||||
&Who::Other => return Err(ParseError::InvalidBit),
|
||||
&Who::User => self.bits.push(Bit::Suid),
|
||||
&Who::Group => self.bits.push(Bit::Sgid),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
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() {
|
||||
for w in &self.who {
|
||||
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();
|
||||
&Who::User | &Who::Group => return Err(ParseError::InvalidBit),
|
||||
&Who::Other => self.bits.push(Bit::Sticky),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn add_bits(&mut self) {
|
||||
for bit in &self.bits {
|
||||
self.mode |= *bit as u32;
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_bits(&mut self) {
|
||||
for bit in &self.bits {
|
||||
self.mode &= *bit as u32;
|
||||
}
|
||||
}
|
||||
|
||||
fn set_bits(&mut self) -> Result<(), ParseError> {
|
||||
match self.op {
|
||||
Some(Op::Add) => self.add_bits(),
|
||||
Some(Op::Remove) => self.remove_bits(),
|
||||
Some(Op::Equals) => {
|
||||
for w in &self.who {
|
||||
match w {
|
||||
Who::User => self.mode &= 0o4444,
|
||||
Who::Group => self.mode &= 0o2222,
|
||||
Who::Other => self.mode &= 0o1111,
|
||||
}
|
||||
}
|
||||
self.add_bits();
|
||||
},
|
||||
None => return Err(ParseError::NoOpSet),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn reset(&mut self) {
|
||||
@ -293,17 +212,28 @@ impl Parser {
|
||||
'u' => self.add_who(Who::User)?,
|
||||
'g' => self.add_who(Who::Group)?,
|
||||
'o' => self.add_who(Who::Other)?,
|
||||
'a' => self.add_who(Who::All)?,
|
||||
'a' => {
|
||||
self.add_who(Who::User)?;
|
||||
self.add_who(Who::Group)?;
|
||||
self.add_who(Who::Other)?;
|
||||
},
|
||||
'-' => 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()?,
|
||||
'r' => self.push_read_bits()?,
|
||||
'w' => self.push_write_bits()?,
|
||||
'x' => self.push_exec_bits()?,
|
||||
's' => self.push_suid_sgid()?,
|
||||
't' => self.push_sticky()?,
|
||||
_ => return Err(ParseError::InvalidDigit),
|
||||
}
|
||||
}
|
||||
self.set_bits();
|
||||
if self.who.is_empty() {
|
||||
self.who.push(Who::User);
|
||||
self.who.push(Who::Group);
|
||||
self.who.push(Who::Other);
|
||||
}
|
||||
self.set_bits()?;
|
||||
self.reset();
|
||||
Ok(self.mode)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user