| 109 | } |
| 110 | |
| 111 | fn parse_mode(line: &str) -> Result<(u32, u32, u32)> { |
| 112 | let mut parts = line.split(' ').skip(1); |
| 113 | // An empty mode resets to defaults |
| 114 | let uid = if let Some(u) = parts.next() { |
| 115 | u |
| 116 | } else { |
| 117 | return Ok((0, 0, 0o644)); |
| 118 | }; |
| 119 | let gid = parts.next().ok_or_else(|| anyhow!("Missing gid"))?; |
| 120 | let mode = parts.next().ok_or_else(|| anyhow!("Missing mode"))?; |
| 121 | if parts.next().is_some() { |
| 122 | anyhow::bail!("Invalid mode: {}", line); |
| 123 | } |
| 124 | Ok((uid.parse()?, gid.parse()?, u32::from_str_radix(mode, 8)?)) |
| 125 | } |
| 126 | |
| 127 | impl FileDef { |
| 128 | /// Parse a list of newline-separated file definitions. |