1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
use std::char; use std::ffi::OsString; use std::fs::File; use std::io::{BufRead, BufReader, Error, ErrorKind, Result}; use std::os::unix::ffi::OsStringExt; pub struct Mount { pub source: OsString, pub dest: OsString, pub fs: OsString, pub options: OsString, pub dump: OsString, pub pass: OsString, } impl Mount { fn parse_value(value: &str) -> Result<OsString> { let mut ret = Vec::new(); let mut bytes = value.bytes(); while let Some(b) = bytes.next() { match b { b'\\' => { let mut code = 0; for _i in 0..3 { if let Some(b) = bytes.next() { code *= 8; code += u32::from_str_radix(&(b as char).to_string(), 8) .map_err(|err| Error::new(ErrorKind::Other, err))?; } else { return Err(Error::new(ErrorKind::Other, "truncated octal code")); } } ret.push(code as u8); } _ => { ret.push(b); } } } Ok(OsString::from_vec(ret)) } fn parse_line(line: &str) -> Result<Mount> { let mut parts = line.split(' '); let source = parts .next() .ok_or(Error::new(ErrorKind::Other, "Missing source"))?; let dest = parts .next() .ok_or(Error::new(ErrorKind::Other, "Missing dest"))?; let fs = parts .next() .ok_or(Error::new(ErrorKind::Other, "Missing fs"))?; let options = parts .next() .ok_or(Error::new(ErrorKind::Other, "Missing options"))?; let dump = parts .next() .ok_or(Error::new(ErrorKind::Other, "Missing dump"))?; let pass = parts .next() .ok_or(Error::new(ErrorKind::Other, "Missing pass"))?; Ok(Mount { source: Self::parse_value(&source)?, dest: Self::parse_value(&dest)?, fs: Self::parse_value(&fs)?, options: Self::parse_value(&options)?, dump: Self::parse_value(&dump)?, pass: Self::parse_value(&pass)?, }) } pub fn all() -> Result<Vec<Mount>> { let mut ret = Vec::new(); let file = BufReader::new(File::open("/proc/self/mounts")?); for line_res in file.lines() { let line = line_res?; ret.push(Self::parse_line(&line)?); } Ok(ret) } }