From b5abe4538f3c7828818ce1a6270e24473dc20b4d Mon Sep 17 00:00:00 2001 From: ChristianVisintin Date: Tue, 22 Dec 2020 17:23:16 +0100 Subject: [PATCH] Replaced sha256 sum with last modification time check, to verify if a file has been changed in the text editor --- CHANGELOG.md | 3 + Cargo.lock | 41 ---------- Cargo.toml | 5 -- README.md | 2 +- .../filetransfer_activity/session.rs | 29 +++---- src/utils/hash.rs | 75 ------------------- src/utils/mod.rs | 1 - 7 files changed, 19 insertions(+), 137 deletions(-) delete mode 100644 src/utils/hash.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index d7a3e42..56c0f21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,9 @@ FIXME: Released on +- Enhancements: + - Replaced sha256 sum with last modification time check, to verify if a file has been changed in the text editor + ## 0.2.0 Released on 21/12/2020 diff --git a/Cargo.lock b/Cargo.lock index 3e76a2e..f0da32c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -272,12 +272,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "data-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993a608597367c6377b258c25d7120740f00ed23a2252b729b1932dd7866f908" - [[package]] name = "debug-helper" version = "0.3.10" @@ -622,12 +616,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "once_cell" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" - [[package]] name = "opaque-debug" version = "0.3.0" @@ -831,21 +819,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "ring" -version = "0.16.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "024a1e66fea74c66c66624ee5622a7ff0e4b73a13b4f5c326ddb50c708944226" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi", -] - [[package]] name = "rpassword" version = "5.0.0" @@ -984,12 +957,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "ssh2" version = "0.9.0" @@ -1035,7 +1002,6 @@ dependencies = [ "chrono", "content_inspector", "crossterm", - "data-encoding", "dirs", "edit", "ftp4", @@ -1045,7 +1011,6 @@ dependencies = [ "magic-crypt", "rand", "regex", - "ring", "rpassword", "serde", "ssh2", @@ -1145,12 +1110,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - [[package]] name = "users" version = "0.11.0" diff --git a/Cargo.toml b/Cargo.toml index c0ae1a1..ab67057 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,15 +37,10 @@ toml = "0.5.7" tui = { version = "0.13.0", features = ["crossterm"], default-features = false } unicode-width = "0.1.7" whoami = "1.0.0" -ring = "0.16.19" -data-encoding = "2.3.1" [target.'cfg(any(target_os = "unix", target_os = "macos", target_os = "linux"))'.dependencies] users = "0.11.0" -#[patch.crates-io] -#ftp = { git = "https://github.com/ChristianVisintin/rust-ftp" } - [[bin]] name = "termscp" path = "src/main.rs" diff --git a/README.md b/README.md index f053973..ec488da 100644 --- a/README.md +++ b/README.md @@ -228,7 +228,7 @@ As said before, bookmarks are saved in your configuration directory along with p ## Text Editor ✏ TermSCP has, as you might have noticed, many features, one of these is the possibility to view and edit text file. It doesn't matter if the file is located on the local host or on the remote host, termscp provides the possibility to open a file in your favourite text editor. -In case the file is located on remote host, the file will be first downloaded into your temporary file directory and then, **only** if changes were made to the file, re-uploaded to the remote host. TermSCP checks if you made changes to the file calculating the digest of the file using `sha256`. +In case the file is located on remote host, the file will be first downloaded into your temporary file directory and then, **only** if changes were made to the file, re-uploaded to the remote host. TermSCP checks if you made changes to the file verifying the last modification time of the file. Just a reminder: **you can edit only textual file**; binary files are not supported. diff --git a/src/ui/activities/filetransfer_activity/session.rs b/src/ui/activities/filetransfer_activity/session.rs index 7f7263a..e090f06 100644 --- a/src/ui/activities/filetransfer_activity/session.rs +++ b/src/ui/activities/filetransfer_activity/session.rs @@ -29,7 +29,6 @@ extern crate tempfile; use super::{FileTransferActivity, InputMode, LogLevel, PopupType}; use crate::fs::{FsEntry, FsFile}; use crate::utils::fmt::fmt_millis; -use crate::utils::hash::hash_sha256_file; // Ext use bytesize::ByteSize; @@ -37,7 +36,7 @@ use crossterm::terminal::{disable_raw_mode, enable_raw_mode}; use std::fs::OpenOptions; use std::io::{Read, Seek, Write}; use std::path::{Path, PathBuf}; -use std::time::Instant; +use std::time::{Instant, SystemTime}; use tui::style::Color; impl FileTransferActivity { @@ -781,13 +780,14 @@ impl FileTransferActivity { if let Err(err) = self.filetransfer_recv_file(tmpfile.path(), file) { return Err(err); } - // Get current file hash - let prev_hash: String = match hash_sha256_file(tmpfile.path()) { - Ok(s) => s, + // Get current file modification time + let prev_mtime: SystemTime = match self.context.as_ref().unwrap().local.stat(tmpfile.path()) + { + Ok(e) => e.get_last_change_time(), Err(err) => { return Err(format!( - "Could not get sha256 for \"{}\": {}", - file.abs_path.display(), + "Could not stat \"{}\": {}", + tmpfile.path().display(), err )) } @@ -796,19 +796,20 @@ impl FileTransferActivity { if let Err(err) = self.edit_local_file(tmpfile.path()) { return Err(err); } - // Check if file has changed - let new_hash: String = match hash_sha256_file(tmpfile.path()) { - Ok(s) => s, + // Get local fs entry + let tmpfile_entry: FsEntry = match self.context.as_ref().unwrap().local.stat(tmpfile.path()) + { + Ok(e) => e, Err(err) => { return Err(format!( - "Could not get sha256 for \"{}\": {}", - file.abs_path.display(), + "Could not stat \"{}\": {}", + tmpfile.path().display(), err )) } }; - // If hash is different, write changes - match new_hash != prev_hash { + // Check if file has changed + match prev_mtime != tmpfile_entry.get_last_change_time() { true => { self.log( LogLevel::Info, diff --git a/src/utils/hash.rs b/src/utils/hash.rs deleted file mode 100644 index ea87645..0000000 --- a/src/utils/hash.rs +++ /dev/null @@ -1,75 +0,0 @@ -//! ## Hash -//! -//! `hash` is the module which provides utilities for calculating digests - -/* -* -* Copyright (C) 2020 Christian Visintin - christian.visintin1997@gmail.com -* -* This file is part of "TermSCP" -* -* TermSCP is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* TermSCP is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with TermSCP. If not, see . -* -*/ - -extern crate data_encoding; -extern crate ring; - -use data_encoding::HEXLOWER; -use ring::digest::{Context, Digest, SHA256}; -use std::fs::File; -use std::io::Read; -use std::path::Path; - -/// ### hash_sha256_file -/// -/// Get SHA256 of provided path -pub fn hash_sha256_file(file: &Path) -> Result { - // Open file - let mut reader: File = File::open(file)?; - let mut context = Context::new(&SHA256); - let mut buffer = [0; 8192]; - loop { - let count = reader.read(&mut buffer)?; - if count == 0 { - break; - } - context.update(&buffer[..count]); - } - // Finish context - let digest: Digest = context.finish(); - Ok(HEXLOWER.encode(digest.as_ref())) -} - -#[cfg(test)] -mod tests { - - use super::*; - - use std::io::Write; - - #[test] - fn test_utils_hash_sha256() { - let tmp: tempfile::NamedTempFile = tempfile::NamedTempFile::new().unwrap(); - // Write - let mut fhnd: File = File::create(tmp.path()).unwrap(); - assert!(fhnd.write_all(b"Hello world!\n").is_ok()); - assert_eq!( - *hash_sha256_file(tmp.path()).ok().as_ref().unwrap(), - String::from("0ba904eae8773b70c75333db4de2f3ac45a8ad4ddba1b242f0b3cfc199391dd8") - ); - // Bad file - assert!(hash_sha256_file(Path::new("/tmp/oiojjt5ig/aiehgoiwg")).is_err()); - } -} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 7c02112..5a3dd3f 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -25,5 +25,4 @@ // modules pub mod fmt; -pub mod hash; pub mod parser;