Replaced sha256 sum with last modification time check, to verify if a file has been changed in the text editor

This commit is contained in:
ChristianVisintin 2020-12-22 17:23:16 +01:00
parent 7202b19d45
commit b5abe4538f
7 changed files with 19 additions and 137 deletions

View file

@ -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

41
Cargo.lock generated
View file

@ -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"

View file

@ -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"

View file

@ -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.

View file

@ -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,

View file

@ -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 <http://www.gnu.org/licenses/>.
*
*/
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<String, std::io::Error> {
// 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());
}
}

View file

@ -25,5 +25,4 @@
// modules
pub mod fmt;
pub mod hash;
pub mod parser;