From cd6bcd3613c2a511ddf1f19f5739493de2c5a278 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Mon, 7 Jan 2019 20:23:02 +0000 Subject: Implement call to import to capture QR code --- src/main.rs | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index 04140ed..b3fb3f3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,8 +2,39 @@ //! Reads OTP configuration from a QR code and writes it to an OTP slot on a Nitrokey device. +use std::fmt; +use std::fs; +use std::io; +use std::path; use std::process; +#[derive(Debug)] +enum Error { + IoError(io::Error), + Error(String), +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + Error::IoError(ref err) => write!(f, "IO error: {}", err), + Error::Error(ref string) => write!(f, "Error: {}", string), + } + } +} + +impl From<&str> for Error { + fn from(string: &str) -> Error { + Error::Error(string.to_string()) + } +} + +impl From for Error { + fn from(error: io::Error) -> Error { + Error::IoError(error) + } +} + #[derive(Debug)] struct Options { slot: u8, @@ -41,9 +72,46 @@ fn parse_options() -> Result { Ok(options) } +fn import_qr_code() -> Result { + let mut temp = mktemp::Temp::new_file()?; + let path = temp.to_path_buf(); + + let status = process::Command::new("import").arg(&path).status()?; + + if status.success() { + temp.release(); + Ok(path) + } else { + match status.code() { + Some(code) => Err(Error::Error(format!( + "import failed with error code {}", + code + ))), + None => Err(Error::from("import was terminated by a signal")), + } + } +} + +fn run(options: Options) -> Result<(), Error> { + let path = match options.file { + Some(ref file) => path::PathBuf::from(file), + None => import_qr_code()?, + }; + if options.file.is_none() { + fs::remove_file(&path)?; + } + Ok(()) +} + fn main() { let status = match parse_options() { - Ok(_) => 0, + Ok(options) => match run(options) { + Ok(()) => 0, + Err(err) => { + println!("{}", err); + 1 + } + }, Err(err) => err, }; process::exit(status); -- cgit v1.2.1