From cfe1e1b0623300376b38288de3f76e387bd20d8f Mon Sep 17 00:00:00 2001 From: Oleksandr Kozachuk Date: Sun, 18 Dec 2022 14:46:22 +0100 Subject: [PATCH] First version of the dump command. --- src/parser.rs | 6 +++++- src/repl.rs | 24 +++++++++++++++++++++--- src/structs.rs | 7 +++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 0fa0890..bcfa6e0 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,7 +1,7 @@ extern crate peg; use crate::password::Password; -use crate::structs::{Command, LKErr, Mode}; +use crate::structs::{Command, LKErr, Mode }; use chrono::naive::NaiveDate; use chrono::Local; use std::{cell::RefCell, rc::Rc}; @@ -18,6 +18,8 @@ peg::parser! { / rm_cmd() / pb_cmd() / source_cmd() + / dump_cmd() + / dump_def_cmd() / enc_cmd() / pass_cmd() / unpass_cmd() @@ -81,6 +83,8 @@ peg::parser! { rule help_cmd() -> Command<'input> = "help" { Command::Help } rule quit_cmd() -> Command<'input> = "quit" { Command::Quit } rule pb_cmd() -> Command<'input> = "pb" _ e:$(([' '..='~'])+) { Command::PasteBuffer(e.to_string()) } + rule dump_cmd() -> Command<'input> = "dump" _ s:$(([' '..='~'])+) { Command::Dump(Some(s.to_string())) } + rule dump_def_cmd() -> Command<'input> = "dump" { Command::Dump(None) } rule source_cmd() -> Command<'input> = "source" _ s:$(([' '..='~'])+) { Command::Source(s.to_string()) } rule ls_cmd() -> Command<'input> = "ls" f:comment()? { Command::Ls(f.unwrap_or(".".to_string())) } rule add_cmd() -> Command<'input> = "add" _ name:name() { Command::Add(Rc::new(RefCell::new(name))) } diff --git a/src/repl.rs b/src/repl.rs index 34f642b..ffe7d1b 100644 --- a/src/repl.rs +++ b/src/repl.rs @@ -6,13 +6,13 @@ use std::{cell::RefCell, rc::Rc}; use std::io::{Write, BufWriter}; use std::io::{BufRead, BufReader}; use std::fs; -use std::collections::HashSet; +use std::collections::{ HashSet, HashMap }; use sha1::{Digest, Sha1}; use crate::lk::LK; use crate::parser::command_parser; -use crate::password::{fix_password_recursion, PasswordRef}; -use crate::structs::{Command, LKErr, Radix, HISTORY_FILE, CORRECT_FILE}; +use crate::password::{ fix_password_recursion, PasswordRef, NameRef }; +use crate::structs::{ Command, LKErr, Radix, HISTORY_FILE, CORRECT_FILE, DUMP_FILE }; use crate::utils::{ call_cmd_with_input, get_copy_command_from_env, get_cmd_args_from_command }; #[derive(Debug)] @@ -249,6 +249,23 @@ impl<'a> LKEval<'a> { }; } + fn cmd_dump(&self, out: &mut Vec, err: &mut Vec, script: &Option) { + let script = match script { Some(p) => p, None => DUMP_FILE.to_str().unwrap() }; + let script = shellexpand::full(script).unwrap().into_owned(); + fn save_dump(data: &HashMap, script: &String) -> std::io::Result<()> { + let file = fs::File::create(script)?; + let mut writer = BufWriter::new(file); + for (_, pwd) in data { + writeln!(writer, "add {}", pwd.borrow().to_string())? + } + Ok(()) + } + match save_dump(&self.state.borrow().db, &script) { + Ok(()) => out.push(format!("Passwords dumped to {}", script)), + Err(e) => err.push(format!("error: failed to dump passswords to {}: {}", script, e.to_string())), + }; + } + fn cmd_ls(&self, out: &mut Vec, err: &mut Vec, filter: String) { let re = match Regex::new(&filter) { Ok(re) => re, @@ -367,6 +384,7 @@ impl<'a> LKEval<'a> { Command::Enc(name) => { self.cmd_enc(Some(&mut out), Some(&mut err), name); }, Command::PasteBuffer(command) => self.cmd_pb(&mut out, &mut err, command), Command::Source(script) => self.cmd_source(&mut out, &mut err, script), + Command::Dump(script) => self.cmd_dump(&mut out, &mut err, script), Command::Pass(name) => match self.get_password(name) { Some(p) => { self.state.borrow_mut().secrets.insert( diff --git a/src/structs.rs b/src/structs.rs index 6e0c3f4..389e6c8 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -22,6 +22,12 @@ lazy_static! { _ => home_dir().unwrap().join(".lesskey_correct").into_boxed_path(), } }; + pub static ref DUMP_FILE: Box = { + match std::env::var("LESSKEY_DUMP") { + Ok(v) => Path::new(shellexpand::full(&v).unwrap().into_owned().as_str()).to_path_buf().into_boxed_path(), + _ => home_dir().unwrap().join(".lesskey_dump").into_boxed_path(), + } + }; } #[derive(thiserror::Error, Debug, PartialEq)] @@ -47,6 +53,7 @@ pub enum Command<'a> { Uncorrect(Name), PasteBuffer(String), Source(String), + Dump(Option), Comment(Name, Comment), Error(LKErr<'a>), Noop,