use std::env; use std::fs; use std::path::Path; pub mod crypt; pub mod archive; pub mod clipboard; pub mod print; pub mod config; pub mod random; pub mod prompt; pub mod cache; pub mod process; pub mod remote; use archive::Archive; use config::Config; use crypt::DecryptError; use process::ProcessError; fn main() { let args: Vec = env::args().collect(); if args.len() <= 1 { print::help(&args[0]); std::process::exit(1); } // load config let configfile = match env::var("CONFIGFILE") { Ok(val) => val, _ => config::default_xdg_homepath("XDG_CONFIG_HOME", ".config", "/etc") + "/zpass/default.conf" }; let configpath = Path::new(&configfile); let conf = Config::get( match configpath.is_file() || configpath.is_symlink() { true => Some(configpath), false => None, } ); if conf.remote_addr.is_some() { todo!(); } // check integrity of file let filepath = conf.path.join(conf.file().clone() + &conf.extension); if filepath.exists() && ! filepath.is_file() { eprintln!("File error"); eprintln!("{} exists and is not a file", filepath.to_str().unwrap()); std::process::exit(2); } // non-decrypt operations let t = process::predecrypt_process(&conf, &args[..]); if t != None { return (); } // read and decrypt file let fullcontents = fs::read(&filepath).expect("Error on read"); let t = process::try_decrypt(&conf, &fullcontents); if t.is_err() { let r = match t.err().unwrap() { DecryptError::BadFormat => (11, "Bad file format"), DecryptError::BadDecrypt => (12, "Failed to decrypt file"), DecryptError::Abort => (13, "Aborted"), }; eprintln!("{}", r.1); std::process::exit(r.0); } let (decrypted, mut password) = t.unwrap(); // generate archive let archive = Archive::from(&decrypted); let r = process::process(&conf, &args[..], &archive.to_ref()); if r.is_err() { let status = match r.err().unwrap() { ProcessError::BadFile => (11, "bad input file"), ProcessError::BadDecrypt => (12, "cannot decrypt file"), ProcessError::Abort => (13, "aborted"), ProcessError::KeysDontMatch => (14, "keys don't match"), ProcessError::MissingArg => (15, "missing argument(s)"), ProcessError::PathNotFound => (16, "path not found"), ProcessError::PathAlreadyExists => (17, "path already exists"), ProcessError::PathConflict => (18, "path conflict"), ProcessError::FileNotFound => (19, "file not found"), ProcessError::FileExists => (20, "file exists"), ProcessError::FileRead => (21, "file read error"), ProcessError::FileWrite => (22, "file write error"), ProcessError::FileDelete => (23, "file delete error"), ProcessError::RemoteError => (24, "remote error"), }; eprintln!("{}", status.1); std::process::exit(status.0); } match r.ok().unwrap() { Some(d) => { let mut t = d.0.to_ref(); t.sort(); let data = t.generate(); if d.1.is_some() { password = d.1.unwrap(); } fs::write(&filepath, crypt::encrypt(&data, &password) ).expect("Error on write"); }, None => (), }; }