(s: &str)
| 158 | } |
| 159 | |
| 160 | pub(crate) fn parse(s: &str) -> Result<Option<SysusersEntry>> { |
| 161 | let err = || Error::ParseFailure(s.to_owned()); |
| 162 | let (ftype, s) = Self::next_token(s).ok_or_else(err)?; |
| 163 | let r = match ftype { |
| 164 | "u" | "u!" => { |
| 165 | let (name, s) = Self::next_token_owned(s).ok_or_else(err)?; |
| 166 | let (id, s) = Self::next_optional_token(s).unwrap_or_default(); |
| 167 | let (uid, pgid) = id |
| 168 | .and_then(|v| v.split_once(':')) |
| 169 | .or_else(|| id.map(|id| (id, id))) |
| 170 | .map(|(uid, gid)| (Some(uid), Some(gid))) |
| 171 | .unwrap_or((None, None)); |
| 172 | let uid = uid |
| 173 | .filter(|&v| v != "-") |
| 174 | .map(|id| id.parse()) |
| 175 | .transpose() |
| 176 | .map_err(|_| err())?; |
| 177 | let pgid = pgid.map(|id| id.parse()).transpose().map_err(|_| err())?; |
| 178 | let (gecos, s) = Self::next_token(s).unwrap_or_default(); |
| 179 | let gecos = gecos.to_owned(); |
| 180 | let (home, s) = Self::next_optional_token_owned(s).unwrap_or_default(); |
| 181 | let (shell, _) = Self::next_optional_token_owned(s).unwrap_or_default(); |
| 182 | SysusersEntry::User { |
| 183 | name, |
| 184 | uid, |
| 185 | pgid, |
| 186 | gecos, |
| 187 | home, |
| 188 | shell, |
| 189 | } |
| 190 | } |
| 191 | "g" => { |
| 192 | let (name, s) = Self::next_token_owned(s).ok_or_else(err)?; |
| 193 | let (id, _) = Self::next_optional_token(s).unwrap_or_default(); |
| 194 | let id = id.map(|id| id.parse()).transpose().map_err(|_| err())?; |
| 195 | SysusersEntry::Group { name, id } |
| 196 | } |
| 197 | "r" => { |
| 198 | let (_, s) = Self::next_optional_token(s).ok_or_else(err)?; |
| 199 | let (range, _) = Self::next_token(s).ok_or_else(err)?; |
| 200 | let (start, end) = range.split_once('-').ok_or_else(err)?; |
| 201 | let start: u32 = start.parse().map_err(|_| err())?; |
| 202 | let end: u32 = end.parse().map_err(|_| err())?; |
| 203 | SysusersEntry::Range { start, end } |
| 204 | } |
| 205 | // In the case of a sysusers entry that is of unknown type, we skip it out of conservatism |
| 206 | _ => return Ok(None), |
| 207 | }; |
| 208 | Ok(Some(r)) |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | /// Read all tmpfiles.d entries in the target directory, and return a mapping |
no outgoing calls
no test coverage detected