109 lines
3.5 KiB
Rust
109 lines
3.5 KiB
Rust
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<String> = 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 => (),
|
|
};
|
|
}
|