1use crate::{Mode, User, Protection, ProtectionBit, Special, SpecialBit};
2use std::str::FromStr;
3use std::iter::Peekable;
4use std::str::Chars;
5use std::num::ParseIntError;
6use std::fmt::{self, Display};
7use std::error::Error;
8
9#[derive(Debug)]
11pub enum ModeParseError {
12 UnexpectedChar(&'static str, char),
13 UnexpectedEnd(&'static str),
14 OctalParseError(ParseIntError),
15}
16
17impl Display for ModeParseError {
18 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19 use ModeParseError::*;
20 match self {
21 UnexpectedChar(expected, c) => write!(f, "unexpected character '{}', expected: {}", c, expected),
22 UnexpectedEnd(expected) => write!(f, "unexpected end of string, expected: {}", expected),
23 OctalParseError(_) => write!(f, "failed to parse octal value"),
24 }
25 }
26}
27
28impl Error for ModeParseError {
29 fn source(&self) -> Option<&(dyn Error + 'static)> {
30 use ModeParseError::*;
31 match self {
32 UnexpectedChar(_, _) => None,
33 UnexpectedEnd(_) => None,
34 OctalParseError(err) => Some(err),
35 }
36 }
37}
38
39#[derive(Debug)]
44struct Users(Vec<User>);
45
46impl Users {
47 fn parse(chars: &mut Peekable<Chars>) -> Users {
48 use User::*;
49 let mut users = Vec::new();
50 loop {
51 match chars.peek() {
52 Some('u') => { users.push(Owner); },
53 Some('g') => { users.push(Group); },
54 Some('o') => { users.push(Other); },
55 Some('a') => {
56 users.push(Owner);
57 users.push(Group);
58 users.push(Other);
59 }
60 _ => return Users(users)
61 }
62 chars.next();
63 }
64 }
65}
66
67#[derive(Debug)]
69enum Operator {
70 Add,
71 Sub,
72 Set,
73}
74
75impl Operator {
76 fn parse(chars: &mut Peekable<Chars>) -> Result<Operator, ModeParseError> {
77 use Operator::*;
78 let c = chars.next().ok_or(ModeParseError::UnexpectedEnd("operator"))?;
79 match c {
80 '-' => Ok(Sub),
81 '+' => Ok(Add),
82 '=' => Ok(Set),
83 c => Err(ModeParseError::UnexpectedChar("[-+=]", c))
84 }
85 }
86}
87
88#[derive(Debug)]
90enum Bit {
91 Protection(ProtectionBit),
92 Special(SpecialBit),
93}
94
95impl Bit {
96 fn parse(chars: &mut Peekable<Chars>) -> Result<Bit, ModeParseError> {
97 use ProtectionBit::*;
98 use SpecialBit::*;
99 let c = chars.next().ok_or(ModeParseError::UnexpectedEnd("operator"))?;
100 match c {
101 'r' => Ok(Bit::Protection(Read)),
102 'w' => Ok(Bit::Protection(Write)),
103 'x' => Ok(Bit::Protection(Execute)),
104 'X' => Ok(Bit::Protection(Search)),
105 's' => Ok(Bit::Special(SetId)),
106 't' => Ok(Bit::Special(Sticky)),
107 c => Err(ModeParseError::UnexpectedChar("[rwxXst]", c))
108 }
109 }
110}
111
112#[derive(Debug)]
114enum Value {
115 Bits(Vec<Bit>),
116 Source(User),
117}
118
119impl Value {
120 fn parse(chars: &mut Peekable<Chars>) -> Result<Value, ModeParseError> {
121 use Value::*;
122 use User::*;
123
124 if let Some(c) = chars.peek() {
125 let user = match c {
126 'u' => Some(Owner),
127 'g' => Some(Group),
128 'o' => Some(Other),
129 _ => None,
130 };
131
132 if let Some(user) = user {
133 chars.next();
134 Ok(Source(user))
135 } else {
136 let mut bits = Vec::new();
137
138 while chars.peek().is_some() {
139 bits.push(Bit::parse(chars).unwrap());
140 }
141
142 Ok(Value::Bits(bits))
143 }
144 } else {
145 Ok(Value::Bits(Vec::new()))
146 }
147 }
148}
149
150#[derive(Debug)]
152struct Expression {
153 operator: Operator,
154 value: Value,
155}
156
157impl Expression {
158 fn parse(chars: &mut Peekable<Chars>) -> Result<Expression, ModeParseError> {
159 Ok(Expression {
160 operator: Operator::parse(chars)?,
161 value: Value::parse(chars)?,
162 })
163 }
164}
165
166#[derive(Debug)]
168struct SymbolicMode {
169 users: Users,
170 expressions: Vec<Expression>,
172}
173
174impl SymbolicMode {
175 fn parse(chars: &mut Peekable<Chars>) -> Result<SymbolicMode, ModeParseError> {
176 let users = Users::parse(chars);
177 let mut expressions = Vec::new();
178
179 loop {
180 if chars.peek().is_none() {
181 break
182 }
183
184 expressions.push(Expression::parse(chars)?);
185 }
186
187 if expressions.is_empty() {
188 Err(ModeParseError::UnexpectedEnd("bits or user flags"))
189 } else {
190 Ok(SymbolicMode {
191 users,
192 expressions,
193 })
194 }
195 }
196}
197
198#[derive(Debug)]
200struct OctalMode {
201 operator: Operator,
202 mode: Mode,
203}
204
205impl OctalMode {
206 fn parse(chars: &mut Peekable<Chars>) -> Result<OctalMode, ModeParseError> {
207 let operator = Operator::parse(chars)?;
208
209 let mut mode = String::new();
210 for c in chars {
211 match c {
212 c @ '0'..='7' => mode.push(c),
213 c => return Err(ModeParseError::UnexpectedChar("[0-7]", c)),
214 }
215 }
216
217 if mode.is_empty() {
218 mode.push('0')
219 }
220
221 let mode = u32::from_str_radix(&mode, 8).map_err(ModeParseError::OctalParseError)?;
222
223 Ok(OctalMode {
224 operator,
225 mode: Mode::new(mode, 0o7777),
226 })
227 }
228}
229
230#[derive(Debug)]
232enum ModeString {
233 Symbolic(SymbolicMode),
234 Octal(OctalMode),
235}
236
237impl FromStr for ModeString {
238 type Err = ModeParseError;
239
240 fn from_str(s: &str) -> Result<Self, Self::Err> {
241 let mut chars = s.chars().peekable();
242
243 let mode_string = if s.ends_with(|c| ('0'..='7').contains(&c)) {
244 ModeString::Octal(OctalMode::parse(&mut chars)?)
245 } else {
246 ModeString::Symbolic(SymbolicMode::parse(&mut chars)?)
247 };
248
249 if let Some(c) = chars.next() {
250 Err(ModeParseError::UnexpectedChar("no more characters", c))
251 } else {
252 Ok(mode_string)
253 }
254 }
255}
256
257impl ModeString {
258 fn into_operations(self, ref_mode: u32, umask: u32) -> Vec<(Operator, Mode)> {
260 let mut ops = Vec::new();
261
262 match self {
263 ModeString::Symbolic(symbolic) => {
264 let (users, umask) = if symbolic.users.0.is_empty() {
265 (vec![User::Owner, User::Group, User::Other], umask)
266 } else {
267 (symbolic.users.0, 0o0)
268 };
269
270 for expr in symbolic.expressions {
271 let mut mode = Mode::empty();
272
273 let mut protection = match &expr.operator {
274 Operator::Set => Protection::all_clear(), _ => Protection::empty(),
276 };
277
278 let mut special = Special::empty();
279
280 match expr.value {
281 Value::Bits(bits) => for bit in bits {
282 match bit {
283 Bit::Protection(protection_bit) => protection.set(protection_bit),
284 Bit::Special(special_bit) => special.set(special_bit),
285 }
286 }
287 Value::Source(source_user) => {
288 let mask = match &expr.operator {
289 Operator::Set => 0o777, _ => ref_mode, };
292
293 let mut ref_mode = Mode::new(ref_mode, mask);
294 ref_mode.set(&mode);
295 protection = ref_mode.user_protection(source_user);
296 }
297 }
298
299 for user in &users {
300 mode.set_protection(*user, &protection);
301 mode.set_special(*user, &special);
302 }
303
304 mode.apply_umask(umask);
305
306 ops.push((expr.operator, mode));
307 }
308 }
309 ModeString::Octal(OctalMode { operator, mode }) => ops.push((operator, mode)),
310 }
311
312 ops
313 }
314}
315
316pub(crate) fn mode_set_from_str(mode: &mut Mode, mode_str: &str, umask: u32) -> Result<(), ModeParseError> {
317 for mode_str in mode_str.split(',') {
318 set(mode, mode_str, umask)?;
319 }
320 Ok(())
321}
322
323fn set(target: &mut Mode, mode_str: &str, umask: u32) -> Result<(), ModeParseError> {
329 let ms = ModeString::from_str(mode_str)?;
330
331 for (operator, mode) in ms.into_operations(target.mode, umask) {
332 match operator {
333 Operator::Add => target.add(&mode),
334 Operator::Sub => target.sub(&mode),
335 Operator::Set => target.set(&mode),
336 }
337 }
338
339 Ok(())
340}
341
342#[cfg(test)]
343mod tests {
344 use super::*;
345 use assert_matches::assert_matches;
346
347 #[test]
348 fn test_parse_users() {
349 use User::*;
350
351 let mut i = "a".chars().peekable();
352 assert_eq!(Users::parse(&mut i).0, vec![Owner, Group, Other]);
353 assert!(i.next().is_none());
354
355 let mut i = "uog".chars().peekable();
356 assert_eq!(Users::parse(&mut i).0, vec![Owner, Other, Group]);
357 assert!(i.next().is_none());
358
359 let mut i = "uxog".chars().peekable();
360 assert_eq!(Users::parse(&mut i).0, vec![Owner]);
361 assert_eq!(&i.collect::<String>(), "xog");
362
363 let mut i = "uoxg".chars().peekable();
364 assert_eq!(Users::parse(&mut i).0, vec![Owner, Other]);
365 assert_eq!(&i.collect::<String>(), "xg");
366
367 let mut i = "uogx".chars().peekable();
368 assert_eq!(Users::parse(&mut i).0, vec![Owner, Other, Group]);
369 assert_eq!(&i.collect::<String>(), "x");
370 }
371
372 #[test]
373 fn test_parse_value() {
374 use ProtectionBit::*;
375 use SpecialBit::*;
376
377 let mut i = "".chars().peekable();
378 assert_matches!(Value::parse(&mut i).unwrap(), Value::Bits(bits) => {
379 assert!(bits.is_empty());
380 });
381 assert!(i.next().is_none());
382
383 let mut i = "rwxst".chars().peekable();
384 assert_matches!(Value::parse(&mut i).unwrap(), Value::Bits(bits) => {
385 let mut b = bits.into_iter();
386 assert_matches!(b.next().unwrap(), Bit::Protection(Read));
387 assert_matches!(b.next().unwrap(), Bit::Protection(Write));
388 assert_matches!(b.next().unwrap(), Bit::Protection(Execute));
389 assert_matches!(b.next().unwrap(), Bit::Special(SetId));
390 assert_matches!(b.next().unwrap(), Bit::Special(Sticky));
391 assert!(b.next().is_none());
392 });
393 assert!(i.next().is_none());
394
395 let mut i = "xw".chars().peekable();
396 assert_matches!(Value::parse(&mut i).unwrap(), Value::Bits(bits) => {
397 let mut b = bits.into_iter();
398 assert_matches!(b.next().unwrap(), Bit::Protection(Execute));
399 assert_matches!(b.next().unwrap(), Bit::Protection(Write));
400 assert!(b.next().is_none());
401 });
402 assert!(i.next().is_none());
403
404 let mut i = "u".chars().peekable();
405 assert_matches!(Value::parse(&mut i).unwrap(), Value::Source(User::Owner));
406 assert!(i.next().is_none());
407
408 let mut i = "g".chars().peekable();
409 assert_matches!(Value::parse(&mut i).unwrap(), Value::Source(User::Group));
410 assert!(i.next().is_none());
411
412 let mut i = "o".chars().peekable();
413 assert_matches!(Value::parse(&mut i).unwrap(), Value::Source(User::Other));
414 assert!(i.next().is_none());
415
416 let mut i = "oo?".chars().peekable();
417 assert_matches!(Value::parse(&mut i).unwrap(), Value::Source(User::Other));
418 assert_eq!(i.next(), Some('o'));
419 }
420
421 #[test]
422 fn test_parse_symbolic_mode() {
423 use User::*;
424
425 let mut i = "u+r".chars().peekable();
426 assert_matches!(SymbolicMode::parse(&mut i).unwrap(), SymbolicMode { users, expressions } => {
427 assert_eq!(users.0, vec![Owner]);
428
429 let mut e = expressions.into_iter();
430 assert_matches!(e.next().unwrap(), Expression { operator: Operator::Add, value } => {
431 assert_matches!(value, Value::Bits(bits) => {
432 let mut b = bits.into_iter();
433 assert_matches!(b.next().unwrap(), Bit::Protection(ProtectionBit::Read));
434 assert!(b.next().is_none());
435 });
436 });
437 assert!(e.next().is_none());
438 });
439 assert!(i.next().is_none());
440
441 let mut i = "=rs".chars().peekable();
442 assert_matches!(SymbolicMode::parse(&mut i).unwrap(), SymbolicMode { users, expressions } => {
443 assert_eq!(users.0, vec![]);
444
445 let mut e = expressions.into_iter();
446 assert_matches!(e.next().unwrap(), Expression { operator: Operator::Set, value } => {
447 assert_matches!(value, Value::Bits(bits) => {
448 let mut b = bits.into_iter();
449 assert_matches!(b.next().unwrap(), Bit::Protection(ProtectionBit::Read));
450 assert_matches!(b.next().unwrap(), Bit::Special(SpecialBit::SetId));
451 assert!(b.next().is_none());
452 });
453 });
454 assert!(e.next().is_none());
455 });
456 assert!(i.next().is_none());
457
458 let mut i = "a=u".chars().peekable();
459 assert_matches!(SymbolicMode::parse(&mut i).unwrap(), SymbolicMode { users, expressions } => {
460 assert_eq!(users.0, vec![Owner, Group, Other]);
461
462 let mut e = expressions.into_iter();
463 assert_matches!(e.next().unwrap(), Expression { operator: Operator::Set, value } => {
464 assert_matches!(value, Value::Source(Owner));
465 });
466 assert!(e.next().is_none());
467 });
468 assert!(i.next().is_none());
469 }
470
471 #[test]
472 fn test_parse_octal_mode() {
473 let mut i = "=777".chars().peekable();
474 assert_matches!(OctalMode::parse(&mut i).unwrap(), OctalMode { operator: Operator::Set, mode } => {
475 assert_eq!(mode, Mode::new(0o777, 0o7777));
476 });
477 assert!(i.next().is_none());
478
479 let mut i = "-7".chars().peekable();
480 assert_matches!(OctalMode::parse(&mut i).unwrap(), OctalMode { operator: Operator::Sub, mode } => {
481 assert_eq!(mode, Mode::new(0o007, 0o7777));
482 });
483 assert!(i.next().is_none());
484
485 let mut i = "+23".chars().peekable();
486 assert_matches!(OctalMode::parse(&mut i).unwrap(), OctalMode { operator: Operator::Add, mode } => {
487 assert_eq!(mode, Mode::new(0o023, 0o7777));
488 });
489 assert!(i.next().is_none());
490
491 let mut i = "+023".chars().peekable();
492 assert_matches!(OctalMode::parse(&mut i).unwrap(), OctalMode { operator: Operator::Add, mode } => {
493 assert_eq!(mode, Mode::new(0o023, 0o7777));
494 });
495 assert!(i.next().is_none());
496
497 let mut i = "=".chars().peekable();
498 assert_matches!(OctalMode::parse(&mut i).unwrap(), OctalMode { operator: Operator::Set, mode } => {
499 assert_eq!(mode, Mode::new(0o000, 0o7777));
500 });
501 assert!(i.next().is_none());
502 }
503}