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
use dirs; use dns; use rand; use std::fs::{create_dir_all, rename, File}; use std::io::{Read, Write}; use std::path::PathBuf; use std::time::{SystemTime, UNIX_EPOCH}; pub fn load() -> u64 { let path = dirs::home_dir().unwrap_or(PathBuf::from("/")); let path = path.join(".devguard/clock"); if !path.exists() { let f2 = if let Ok(dr) = SystemTime::now().duration_since(UNIX_EPOCH) { dr.as_secs() * 1000 + dr.subsec_nanos() as u64 / 1_000_000 } else { 1 }; store(f2).ok(); return f2; } let f = File::open(&path).map_err(|e| e.to_string()).and_then(|mut f| { let mut b = String::new(); f.read_to_string(&mut b).map_err(|e| e.to_string()).and_then(|_| { b.parse() .map_err(|e: std::num::ParseIntError| e.to_string()) .and_then(|v| Ok(v)) }) }); let f = match f { Ok(f) => f, Err(e) => { error!( "cannot open time sync file {:?} : {}. falling back to system time", &path, e ); 0 } }; if let Ok(dr) = SystemTime::now().duration_since(UNIX_EPOCH) { let f2 = dr.as_secs() * 1000 + dr.subsec_nanos() as u64 / 1_000_000; if f2 > f { return f2; } } f } pub fn store(i: u64) -> Result<(), String> { let path = dirs::home_dir().unwrap_or(PathBuf::from("/")); let dir = path.join(".devguard/"); create_dir_all(&dir).map_err(|e| e.to_string())?; let r: u64 = rand::random(); let path2 = path.join(format!(".devguard/clock{}", r)); let path = path.join(".devguard/clock"); { let mut f = File::create(&path2).map_err(|e| e.to_string())?; f.write(format!("{}", i).as_bytes()).map_err(|e| e.to_string())?; rename(&path2, &path).map_err(|e| e.to_string())?; f.sync_all().map_err(|e| e.to_string())?; } assert!(load() >= i); Ok(()) } pub fn dns_time(_: &dns::DnsRecord) -> u64 { let mut t = load(); t += 1; if let Err(e) = store(t) { error!("cannot write time sync: {}", e); } t } pub fn network_time() -> u64 { let mut t = load(); t += 1; if let Err(e) = store(t) { error!("cannot write time sync: {}", e); } t }