From 3d1e27919e441996070b89004a71cd6eea5d8ab7 Mon Sep 17 00:00:00 2001 From: Entity Date: Wed, 16 Oct 2024 11:08:52 +0200 Subject: [PATCH] Initial implementation --- SSH-Transfer/Cargo.lock | 228 +++++++++++++++++++++++++++++++++++++ SSH-Transfer/Cargo.toml | 1 + SSH-Transfer/Source/App.rs | 122 +++++++++++++++++++- 3 files changed, 349 insertions(+), 2 deletions(-) diff --git a/SSH-Transfer/Cargo.lock b/SSH-Transfer/Cargo.lock index d126e07..9ea4703 100644 --- a/SSH-Transfer/Cargo.lock +++ b/SSH-Transfer/Cargo.lock @@ -6,9 +6,117 @@ version = 3 name = "SSH-Transfer" version = "0.1.0" dependencies = [ + "clap", "users", ] +[[package]] +name = "anstream" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + +[[package]] +name = "anstyle-parse" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "clap" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + +[[package]] +name = "colorchoice" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "libc" version = "0.2.159" @@ -21,6 +129,47 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "proc-macro2" +version = "1.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + [[package]] name = "users" version = "0.11.0" @@ -30,3 +179,82 @@ dependencies = [ "libc", "log", ] + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/SSH-Transfer/Cargo.toml b/SSH-Transfer/Cargo.toml index d498d5c..0023a90 100644 --- a/SSH-Transfer/Cargo.toml +++ b/SSH-Transfer/Cargo.toml @@ -8,4 +8,5 @@ name = "SSH-Transfer" path = "Source/App.rs" [dependencies] +clap = { version = "4.5.20", features = ["derive"] } users = "0.11.0" diff --git a/SSH-Transfer/Source/App.rs b/SSH-Transfer/Source/App.rs index 405cab3..171ec37 100644 --- a/SSH-Transfer/Source/App.rs +++ b/SSH-Transfer/Source/App.rs @@ -1,5 +1,123 @@ -#[allow(non_snake_case)] +#![allow(non_snake_case)] + +use std::{fs, path::PathBuf, process::exit}; + +use users::{self, os::unix::UserExt}; +use clap::Parser; +use users::{get_current_uid, get_user_by_uid}; + +#[derive(Parser)] +struct CLI +{ + #[arg(long)] + Source : String +} + fn main() { - let CurrentUser = ""; + let Args = CLI::parse(); + + let CurrentUUID = get_current_uid(); + let CurrentUser = get_user_by_uid(CurrentUUID).unwrap(); + let CurrentUserName = CurrentUser.name().to_str().unwrap(); + let CurrentUserHomeDir = CurrentUser.home_dir().to_str().unwrap(); + + #[cfg(debug_assertions)] + println!("Program running from {} with UUID {}", CurrentUserName, CurrentUUID ); + #[cfg(debug_assertions)] + println!("{}'s home directory: {}" , CurrentUserName, CurrentUserHomeDir); + + println!("Copying from {} to {}/.ssh", Args.Source, CurrentUserHomeDir); + + VerifySource(); + CopySource((CurrentUserHomeDir.to_owned()+"/.ssh").as_str()); +} + +fn VerifySource() -> bool +{ + // Verify that the source path exists + let SourceExists = match fs::exists(CLI::parse().Source) { + Ok(FileExists) => + {FileExists}, + Err(Error) => + { + println!("An error occurred checking if {} exists: \n{}", CLI::parse().Source, Error); + exit(1) + }, + }; + + // If the source exists, check if it's a folder + if SourceExists + { + let SourceMetaData = PathBuf::from(CLI::parse().Source); + // If the source is a folder, check the folder structure + // A valid SSH directory should contain a config file + // All identityfiles mentioned in the config shoud also be in this folder + // All files should be readable by us + if SourceMetaData.is_file() + { + println!("{} is a file, while the source flag should be a directory", CLI::parse().Source); + exit(3) + } + else + { + let SourceFolder = fs::read_dir(CLI::parse().Source).unwrap(); + // Make sure a config file exists in the root of the Source folder + + let mut SourceIterator = SourceFolder.into_iter(); + let ConfigFileExists : bool = SourceIterator.any(|file| file.unwrap().file_name().to_str().unwrap() == "config"); + if ConfigFileExists + { + return true; + } + else + { + println!("No config file found in {}", CLI::parse().Source); + exit(4) + } + } + } + else + { + println!("The source folder {} specified is not accesible", CLI::parse().Source); + exit(2); + } +} + +fn CopySource(Destination : &str) +{ + // Make sure the destination exists + let DestExists = match fs::exists(Destination) + { + Ok(Exists) => {Exists}, + Err(Error) => {println!("Could not check if {} exists \n{}", Destination, Error); exit(6)} + }; + + if !DestExists + { + match fs::create_dir(Destination) { + Ok(_) => {}, + Err(Error) => {println!("Could not create {}:{}", Destination, Error.kind().to_string())}, + }; + } + + // Actually copy all of the files + RecursiveCopy(&CLI::parse().Source, Destination); +} + +fn RecursiveCopy(Source : &str, Destination : &str) +{ + for FSNode in fs::read_dir(Source).unwrap() + { + let FSNode = FSNode.unwrap(); + if FSNode.file_type().unwrap().is_dir() + { + // Deepens the path by one, so no infinite loops + RecursiveCopy(FSNode.path().to_str().unwrap(), (Destination.to_owned()+FSNode.file_name().to_str().unwrap()).as_str()); + } + else + { + fs::copy(FSNode.path(), Destination.to_string()+"/"+FSNode.file_name().to_str().unwrap()).unwrap(); + } + } } \ No newline at end of file