mode::Parser - made self.who into u32 and test using bitflags

This commit is contained in:
Nathan Fisher 2023-01-16 16:22:29 -05:00
parent bee6cdf08e
commit 528d2478cd

View File

@ -33,15 +33,15 @@ enum Op {
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
enum Who { enum Who {
User, User = 0o100,
Group, Group = 0o10,
Other, Other = 0o1,
} }
pub struct Parser { pub struct Parser {
mode: u32, mode: u32,
op: Option<Op>, op: Option<Op>,
who: Vec<Who>, who: u32,
bits: Vec<Bit>, bits: Vec<Bit>,
} }
@ -53,7 +53,7 @@ impl Default for Parser {
Self { Self {
mode, mode,
op: None, op: None,
who: vec![], who: 0,
bits: vec![], bits: vec![],
} }
} }
@ -64,7 +64,7 @@ impl Parser {
Self { Self {
mode, mode,
op: None, op: None,
who: vec![], who: 0,
bits: vec![], bits: vec![],
} }
} }
@ -79,10 +79,10 @@ impl Parser {
} }
fn add_who(&mut self, who: Who) -> Result<(), ParseError> { fn add_who(&mut self, who: Who) -> Result<(), ParseError> {
if self.op.is_some() || self.who.contains(&who) || !self.bits.is_empty() { if self.op.is_some() || !self.bits.is_empty() {
Err(ParseError::InvalidDigit) Err(ParseError::InvalidDigit)
} else { } else {
self.who.push(who); self.who |= who as u32;
Ok(()) Ok(())
} }
} }
@ -97,61 +97,63 @@ impl Parser {
} }
fn push_read_bits(&mut self) -> Result<(), ParseError> { fn push_read_bits(&mut self) -> Result<(), ParseError> {
for w in &self.who { if self.who & 0o100 != 0 {
match w { self.bits.push(Bit::URead);
Who::User => self.bits.push(Bit::URead),
Who::Group => self.bits.push(Bit::GRead),
Who::Other => self.bits.push(Bit::ORead),
} }
if self.who & 0o10 != 0 {
self.bits.push(Bit::GRead);
}
if self.who & 0o1 != 0 {
self.bits.push(Bit::ORead);
} }
Ok(()) Ok(())
} }
fn push_write_bits(&mut self) -> Result<(), ParseError> { fn push_write_bits(&mut self) -> Result<(), ParseError> {
for w in &self.who { if self.who & 0o100 != 0 {
match w { self.bits.push(Bit::UWrite);
Who::User => self.bits.push(Bit::UWrite),
Who::Group => self.bits.push(Bit::GWrite),
Who::Other => self.bits.push(Bit::OWrite),
} }
if self.who & 0o10 != 0 {
self.bits.push(Bit::GWrite);
}
if self.who & 0o1 != 0 {
self.bits.push(Bit::OWrite);
} }
Ok(()) Ok(())
} }
fn push_exec_bits(&mut self) -> Result<(), ParseError> { fn push_exec_bits(&mut self) -> Result<(), ParseError> {
for w in &self.who { if self.who & 0o100 != 0 {
match w { self.bits.push(Bit::UExec);
Who::User => self.bits.push(Bit::UExec),
Who::Group => self.bits.push(Bit::GExec),
Who::Other => self.bits.push(Bit::OExec),
} }
if self.who & 0o10 != 0 {
self.bits.push(Bit::GExec);
}
if self.who & 0o1 != 0 {
self.bits.push(Bit::OExec);
} }
Ok(()) Ok(())
} }
fn push_suid_sgid(&mut self) -> Result<(), ParseError> { fn push_suid_sgid(&mut self) -> Result<(), ParseError> {
if self.who.is_empty() { if self.who == 0 || self.who & 0o1 != 0{
return Err(ParseError::InvalidBit); return Err(ParseError::InvalidBit);
} }
for w in &self.who { if self.who & 0o100 != 0 {
match w { self.bits.push(Bit::Suid);
&Who::Other => return Err(ParseError::InvalidBit),
&Who::User => self.bits.push(Bit::Suid),
&Who::Group => self.bits.push(Bit::Sgid),
} }
if self.who &0o10 != 0 {
self.bits.push(Bit::Sgid);
} }
Ok(()) Ok(())
} }
fn push_sticky(&mut self) -> Result<(), ParseError> { fn push_sticky(&mut self) -> Result<(), ParseError> {
if self.who.is_empty() { if self.who == 0 || self.who & 0o100 != 0 || self.who & 0o10 != 0 {
return Err(ParseError::InvalidBit); return Err(ParseError::InvalidBit);
} }
for w in &self.who { if self.who & 0o1 != 0 {
match w { self.bits.push(Bit::Sticky);
&Who::User | &Who::Group => return Err(ParseError::InvalidBit),
&Who::Other => self.bits.push(Bit::Sticky),
}
} }
Ok(()) Ok(())
} }
@ -173,12 +175,14 @@ impl Parser {
Some(Op::Add) => self.add_bits(), Some(Op::Add) => self.add_bits(),
Some(Op::Remove) => self.remove_bits(), Some(Op::Remove) => self.remove_bits(),
Some(Op::Equals) => { Some(Op::Equals) => {
for w in &self.who { if self.who & 0o100 != 0 {
match w { self.mode &= 0o4444;
Who::User => self.mode &= !0o4444,
Who::Group => self.mode &= !0o2222,
Who::Other => self.mode &= !0o1111,
} }
if self.who & 0o10 != 0 {
self.mode &= 0o2222;
}
if self.who &0o1 != 0 {
self.mode &= 0o1111;
} }
self.add_bits(); self.add_bits();
}, },
@ -188,7 +192,7 @@ impl Parser {
} }
fn reset(&mut self) { fn reset(&mut self) {
self.who.clear(); self.who = 0;
self.op = None; self.op = None;
self.bits.clear(); self.bits.clear();
} }
@ -228,10 +232,8 @@ impl Parser {
_ => return Err(ParseError::InvalidDigit), _ => return Err(ParseError::InvalidDigit),
} }
} }
if self.who.is_empty() { if self.who == 0 {
self.who.push(Who::User); self.who |= 0o111;
self.who.push(Who::Group);
self.who.push(Who::Other);
} }
self.set_bits()?; self.set_bits()?;
self.reset(); self.reset();
@ -240,7 +242,7 @@ impl Parser {
pub fn parse_all(&mut self, value: &str) -> Result<u32, ParseError> { pub fn parse_all(&mut self, value: &str) -> Result<u32, ParseError> {
for seg in value.split(',') { for seg in value.split(',') {
self.parse(seg); let _mode = self.parse(seg);
} }
Ok(self.mode()) Ok(self.mode())
} }