From bea5b1d6d935ff51c445fe4c0f766906b29beb1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20Kaan=20G=C3=9CM=C3=9C=C5=9E?= <96421894+Tahinli@users.noreply.github.com> Date: Mon, 30 Oct 2023 00:48:25 +0300 Subject: [PATCH 1/8] feat: start program with environmental args only feat: file generation at receiver side --- src/main.rs | 280 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 172 insertions(+), 108 deletions(-) diff --git a/src/main.rs b/src/main.rs index 49aeb6f..7ebceea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,28 @@ use std::fs::{File, Metadata, self}; +use std::path::{Path, PathBuf}; use std::time::Instant; -use std::net::{TcpListener, TcpStream}; -use std::io::{Read, Write, self, BufWriter, BufReader, BufRead}; +use std::net::{TcpListener, TcpStream, IpAddr}; +use std::io::{Read, Write, BufWriter, BufReader, BufRead}; use std::env::{self}; const BUFFER_SIZE:u64 = 100000; + +#[derive(Debug)] +struct UserEnvironment + { + ip:IpAddr, + port:u16, + server:bool, + send:bool, + location:Option, + debug:DebugMode, + } +#[derive(Debug)] struct FileInfo { file:Option, - location:String, + location:Option, size_current:usize, metadata:Option, } @@ -41,22 +54,21 @@ impl FileInfo } None => { - println!("Error: Read Metadata -> {}", self.location); + println!("Error: Read Metadata -> {}", self.location.as_ref().unwrap()); } } } fn writing_operations(&mut self, stream:&mut TcpStream, debug_mode:&bool) { - self.forge_file(); self.write_file(stream, debug_mode); } fn read_metadata(&mut self) { - self.metadata = Some(fs::metadata(&self.location).expect("Error: Read Metadata")); + self.metadata = Some(fs::metadata(&self.location.as_ref().unwrap()).expect("Error: Read Metadata")); } fn open_file(&mut self) { - match File::open(&self.location) + match File::open(&self.location.as_ref().unwrap()) { Ok(file) => { @@ -64,7 +76,7 @@ impl FileInfo } Err(err_val) => { - println!("Error: Open File -> {} | Error: {}", self.location, err_val); + println!("Error: Open File -> {} | Error: {}", self.location.as_ref().unwrap(), err_val); return; } } @@ -75,7 +87,10 @@ impl FileInfo let size = self.metadata.as_ref().unwrap().len(); let mut iteration = (size/BUFFER_SIZE)+1; let total_iteration = iteration; - self.handshake_validation(stream, size, debug_mode); + let path_buf = PathBuf::from(Path::new(self.location.as_ref().unwrap())); + self.callback_validation(stream, &(size.to_string()), debug_mode); + self.callback_validation(stream, &path_buf.file_name().unwrap().to_str().unwrap().to_string(), debug_mode); + println!("File = {}", self.location.as_ref().unwrap()); println!("Size = {}", size); println!("Iteration = {}", iteration); while iteration != 0 @@ -98,25 +113,25 @@ impl FileInfo println!("%{}", 100 as f64 -((iteration as f64/total_iteration as f64)*100 as f64)); } } - fn handshake_validation(&mut self, stream:&mut TcpStream, size:u64, debug_mode:&bool) + fn callback_validation(&mut self, stream:&mut TcpStream, data:&String, debug_mode:&bool) { - self.send_exact(String::from(size.to_string()+"\n").as_bytes(), stream, debug_mode); + self.send_exact(String::from(data.clone() + "\n").as_bytes(), stream, debug_mode); match self.recv_until(stream, '\n', debug_mode) { - Some(handshake_callback) => + Some(callback_callback) => { - if handshake_callback == size.to_string().as_bytes().to_vec() + if callback_callback == data.to_string().as_bytes().to_vec() { - println!("Done: Handshake -> {}", self.location); + println!("Done: Callback -> {}", self.location.as_ref().unwrap()); if *debug_mode { - println!("{:#?} ", handshake_callback); + println!("{:#?} ", callback_callback); } } else { - println!("Error: Handshake -> {}", self.location); - println!("{:#?} ", handshake_callback); + println!("Error: Callback -> {}", self.location.as_ref().unwrap()); + println!("{:#?} ", callback_callback); panic!() } } @@ -134,13 +149,13 @@ impl FileInfo { if *debug_mode { - println!("Done: Read Bytes -> {}", self.location); + println!("Done: Read Bytes -> {}", self.location.as_ref().unwrap()); println!("{:#?}", buffer); } } Err(err_val) => { - println!("Error: Read Bytes -> {} | Error: {}", self.location, err_val); + println!("Error: Read Bytes -> {} | Error: {}", self.location.as_ref().unwrap(), err_val); panic!() } } @@ -155,13 +170,13 @@ impl FileInfo self.size_current += buffer.len(); if *debug_mode { - println!("Done: Send Bytes -> {}", self.location); + println!("Done: Send Bytes -> {:#?}", self.location); println!("{:#?}", buffer); } } Err(err_val) => { - println!("Error: Send Bytes -> {} | Error: {}", self.location, err_val); + println!("Error: Send Bytes -> {:#?} | Error: {}", self.location, err_val); panic!(); } } @@ -171,12 +186,12 @@ impl FileInfo { if *debug_mode { - println!("Done: Flush -> {}", self.location); + println!("Done: Flush -> {:#?}", self.location); } } Err(err_val) => { - println!("Error: Flush -> {} | Error: {}", self.location, err_val); + println!("Error: Flush -> {:#?} | Error: {}", self.location, err_val); panic!() } } @@ -190,13 +205,13 @@ impl FileInfo self.size_current += buffer.len(); if *debug_mode { - println!("Done: Receive Bytes -> {}", self.location); + println!("Done: Receive Bytes -> {:#?}", self.location); println!("{:#?}", buffer); } } Err(err_val) => { - println!("Error: Receive Bytes -> {} | Error: {}", self.location, err_val); + println!("Error: Receive Bytes -> {:#?} | Error: {}", self.location, err_val); panic!(); } } @@ -211,14 +226,14 @@ impl FileInfo { if *debug_mode { - println!("Done: Receive Until -> {}", self.location); + println!("Done: Receive Until -> {:#?}", self.location); println!("{:#?}", buffer); } buffer.pop(); } Err(err_val) => { - println!("Error: Receive Until -> {} | Error: {}", self.location, err_val); + println!("Error: Receive Until -> {:#?} | Error: {}", self.location, err_val); return None; } } @@ -226,28 +241,39 @@ impl FileInfo } fn forge_file(&mut self) { - self.file = Some(File::create(&self.location).expect("Error: Create File")); - } - fn handshake_recv(&mut self, stream:&mut TcpStream, debug_mode:&bool) -> u64 - { - match self.recv_until(stream, '\n', debug_mode) + match &self.location { - Some(mut handshake) => + Some(location) => { - println!("Done: Handshake -> {}", self.location); - if *debug_mode - { - println!("{:#?} ", handshake); - } - let size = String::from_utf8(handshake.clone()).unwrap().parse().unwrap(); - handshake.push(b'\n'); - self.send_exact(&handshake.as_slice(), stream, debug_mode); - size + self.file = Some(File::create(&location).expect("Error: Create File")); } None => { - println!("Error: Handshake -> {}", self.location); - 0 + println!("Error: Forge File -> {:#?}", self.location); + panic!(); + } + } + } + fn callback_recv(&mut self, stream:&mut TcpStream, debug_mode:&bool) -> String + { + match self.recv_until(stream, '\n', debug_mode) + { + Some(mut callback) => + { + println!("Done: Callback -> {:#?}", self.location); + if *debug_mode + { + println!("{:#?} ", callback); + } + let data = String::from_utf8(callback.clone()).unwrap(); + callback.push(b'\n'); + self.send_exact(&callback.as_slice(), stream, debug_mode); + data + } + None => + { + println!("Error: Callback -> {:#?}", self.location); + panic!(); } } } @@ -260,13 +286,13 @@ impl FileInfo { if *debug_mode { - println!("Done: Write -> {} | {} bytes", self.location, self.size_current); + println!("Done: Write -> {} | {} bytes", self.location.as_ref().unwrap(), self.size_current); println!("{:#?}", buffer); } } Err(err_val) => { - println!("Error: Write -> {} | Error: {}", self.location,err_val); + println!("Error: Write -> {} | Error: {}", self.location.as_ref().unwrap(),err_val); panic!(); } } @@ -276,21 +302,24 @@ impl FileInfo { if *debug_mode { - println!("Done: Flush -> {}", self.location); + println!("Done: Flush -> {}", self.location.as_ref().unwrap()); } } Err(err_val) => { - println!("Error: Flush -> {} | Error: {}", self.location,err_val); + println!("Error: Flush -> {} | Error: {}", self.location.as_ref().unwrap(),err_val); panic!(); } } } fn write_file(&mut self, stream:&mut TcpStream, debug_mode:&bool) { - let size = self.handshake_recv(stream, debug_mode); + let size:u64 = self.callback_recv(stream, debug_mode).parse().unwrap(); + self.location = Some(self.callback_recv(stream, debug_mode)); + self.forge_file(); let mut iteration:u64 = (size/BUFFER_SIZE)+1; let total_iteration = iteration; + println!("File = {}", self.location.as_ref().unwrap()); println!("Size = {}", size); println!("Iteration = {}", iteration); while iteration != 0 @@ -310,13 +339,14 @@ impl FileInfo } } } +#[derive(Debug)] enum DebugMode { On, Off } impl DebugMode { - fn debug_mode(self) -> bool + fn debug_mode(&self) -> bool { match self { @@ -343,9 +373,14 @@ enum Connection impl Connection { - fn server(self, file_info:&mut FileInfo, debug_mode:bool) + fn server(self, file_info:&mut FileInfo, debug_mode:bool, user_environment:&UserEnvironment) { print!("Server -> "); + if debug_mode + { + println!("{:#?}", user_environment); + println!("{:#?}", file_info); + } let ip:String; let port:String; let address:String; @@ -368,7 +403,7 @@ impl Connection Ok(mut stream) => { println!("Connected"); - send_or_receive(file_info, &mut stream, &debug_mode); + send_or_receive(file_info, &mut stream, &debug_mode, user_environment); } Err(e) => { @@ -378,9 +413,14 @@ impl Connection } } } - fn client(self, file_info:&mut FileInfo, debug_mode:bool) + fn client(self, file_info:&mut FileInfo, debug_mode:bool, user_environment:&UserEnvironment) { print!("Client -> "); + if debug_mode + { + println!("{:#?}", user_environment); + println!("{:#?}", file_info); + } let ip:String; let port:String; let address:String; @@ -400,7 +440,7 @@ impl Connection Ok(mut stream) => { println!("Connected"); - send_or_receive(file_info, &mut stream, &debug_mode); + send_or_receive(file_info, &mut stream, &debug_mode, user_environment); } Err(e) => { @@ -410,94 +450,118 @@ impl Connection } } -fn send_or_receive(file_info:&mut FileInfo, stream:&mut TcpStream, debug_mode:&bool) +fn send_or_receive(file_info:&mut FileInfo, stream:&mut TcpStream, debug_mode:&bool, user_environment:&UserEnvironment) { - match &take_string("Input: Send 's', Receive 'r'".to_string())[..1] + match user_environment.send { - "s" => + true => { - println!("Connected"); let start_time = Instant::now(); FileInfo::reading_operations(file_info, stream, &debug_mode); let finish_time = Instant::now(); println!("Passed: Total -> {:#?}", finish_time.duration_since(start_time)); } - "r" => + false => { let start_time = Instant::now(); FileInfo::writing_operations(file_info, stream, &debug_mode); let finish_time = Instant::now(); println!("Passed: Total -> {:#?}", finish_time.duration_since(start_time)); } - input => - { - println!("Error: Give Valid Input, You Gave : {}", input); - panic!() } } } -fn take_string(output:String) -> String +fn take_args(user_environment:&mut UserEnvironment) { - let mut input = String::new(); - println!("{}", output); - io::stdin().read_line(&mut input).expect("Error: Failed to Read from Console"); - input - } -fn take_arg() -> String - { - env::args().last().as_deref().unwrap_or("default").to_string() - } -fn debug_mod() -> DebugMode - { - match &take_string("Input: Debug -> On '1', Debug -> Off '0'".to_string())[0..1] - { - "1" => - { - DebugMode::On - } - "0" => - { - DebugMode::Off - } - input => - { - println!("Error: Give Valid Input, You Gave : {}", input); - panic!() - } - } + let env_args:Vec = env::args().collect(); + if env_args.len() > 15 + { + println!("Error: Too Many Arguments, You Gave {} Arguments", env_args.len()); + panic!(); + } + let mut i = 1; + while i < env_args.len() + { + match env_args[i].as_str() + { + "--ip" => + { + user_environment.ip = env_args[i+1].parse().unwrap(); + i += 1; + } + "--port" => + { + user_environment.port = env_args[i+1].parse().unwrap(); + i += 1; + } + "--location" => + { + user_environment.location = Some(env_args[i+1].parse().unwrap()); + i += 1; + } + "--server" => + { + user_environment.server = true; + } + "--client" => + { + user_environment.server = false; + } + "--send" => + { + user_environment.send = true; + } + "--receive" => + { + user_environment.send = false; + } + "--debug" => + { + user_environment.debug = DebugMode::On; + } + err => + { + println!("Error: Invalid Argument, You Gave {}", err); + } + } + i += 1; + } } fn main() { //DONT FORGET //First we should check folder structure and validation then make connection. + //Until's can be deprecated, 100k byte should be enough for eveything.(Security) println!("Hello, world!"); - - let mut data = FileInfo + let mut user_environment = UserEnvironment + { + ip:"127.0.0.1".parse().unwrap(), + port:2121, + server:false, + send:false, + location:None, + debug:DebugMode::Off, + }; + take_args(&mut user_environment); + let mut file_info = FileInfo { file:None, - location:take_arg(), + location:user_environment.location.clone(), size_current:0 as usize, metadata:None, }; - match &take_string("Input: Server 's', Client 'c'".to_string())[0..1] + match user_environment.server { - "s" => + true => { Connection::server - (Connection::Server(take_string("Input: Server Stream IP Address".to_string()), - take_string("Input: Server Stream Port Address".to_string())), - &mut data, DebugMode::debug_mode(debug_mod())); + (Connection::Server(user_environment.ip.to_string(), user_environment.port.to_string()), + &mut file_info, DebugMode::debug_mode(&user_environment.debug), &user_environment); }, - "c" => + false => { Connection::client - (Connection::Client(take_string("Input: Server IP Address to Connect".to_string()), - take_string("Input: Server Port Address to Connect".to_string())), - &mut data, DebugMode::debug_mode(debug_mod())); - } - input => - { - println!("Error: Give Valid Input, You Gave : {}", input); - return; + (Connection::Client(user_environment.ip.to_string(), user_environment.port.to_string()), + &mut file_info, DebugMode::debug_mode(&user_environment.debug), &user_environment); } } } From 06b27b458589bcc08a7193b0d49cf471d7822c97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20Kaan=20G=C3=9CM=C3=9C=C5=9E?= <96421894+Tahinli@users.noreply.github.com> Date: Mon, 30 Oct 2023 02:07:05 +0300 Subject: [PATCH 2/8] feat: added help menu refactor: debug_mode --- src/main.rs | 83 +++++++++++++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/src/main.rs b/src/main.rs index 7ebceea..5e60a3d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,7 +16,7 @@ struct UserEnvironment server:bool, send:bool, location:Option, - debug:DebugMode, + debug:bool, } #[derive(Debug)] struct FileInfo @@ -339,32 +339,6 @@ impl FileInfo } } } -#[derive(Debug)] -enum DebugMode - { - On, - Off - } -impl DebugMode { - fn debug_mode(&self) -> bool - { - match self - { - DebugMode::On => - { - println!("Debug: ON"); - let debug = true; - debug - } - DebugMode::Off => - { - println!("Debug: OFF"); - let debug = false; - debug - } - } - } -} enum Connection { Server(String, String), @@ -373,10 +347,10 @@ enum Connection impl Connection { - fn server(self, file_info:&mut FileInfo, debug_mode:bool, user_environment:&UserEnvironment) + fn server(self, file_info:&mut FileInfo, user_environment:&UserEnvironment) { print!("Server -> "); - if debug_mode + if user_environment.debug { println!("{:#?}", user_environment); println!("{:#?}", file_info); @@ -403,7 +377,7 @@ impl Connection Ok(mut stream) => { println!("Connected"); - send_or_receive(file_info, &mut stream, &debug_mode, user_environment); + send_or_receive(file_info, &mut stream, &user_environment.debug, user_environment); } Err(e) => { @@ -413,10 +387,10 @@ impl Connection } } } - fn client(self, file_info:&mut FileInfo, debug_mode:bool, user_environment:&UserEnvironment) + fn client(self, file_info:&mut FileInfo, user_environment:&UserEnvironment) { print!("Client -> "); - if debug_mode + if user_environment.debug { println!("{:#?}", user_environment); println!("{:#?}", file_info); @@ -440,7 +414,7 @@ impl Connection Ok(mut stream) => { println!("Connected"); - send_or_receive(file_info, &mut stream, &debug_mode, user_environment); + send_or_receive(file_info, &mut stream, &user_environment.debug, user_environment); } Err(e) => { @@ -470,13 +444,13 @@ fn send_or_receive(file_info:&mut FileInfo, stream:&mut TcpStream, debug_mode:&b } } } -fn take_args(user_environment:&mut UserEnvironment) +fn take_args(user_environment:&mut UserEnvironment) -> bool { let env_args:Vec = env::args().collect(); - if env_args.len() > 15 + if env_args.len() > 16 { println!("Error: Too Many Arguments, You Gave {} Arguments", env_args.len()); - panic!(); + return false; } let mut i = 1; while i < env_args.len() @@ -516,15 +490,39 @@ fn take_args(user_environment:&mut UserEnvironment) } "--debug" => { - user_environment.debug = DebugMode::On; + user_environment.debug = false; } + "--help" => + { + show_help(); + return false; + + } err => { println!("Error: Invalid Argument, You Gave {}", err); + return false; } } i += 1; } + true + } +fn show_help() + { + println!("\n\n\n"); + println!(" Arguments | Details | Defaults"); + println!("--------------------------------------------------------------"); + println!(" --ip | Specify IP Address | 127.0.0.1"); + println!(" --port | Specify Port Address | 2121"); + println!(" --location | Specify Location Address | Same as Program"); + println!(" --server | Start as a Server | False"); + println!(" --client | Start as a Client | True"); + println!(" --send | Start as a Sender | False"); + println!(" --receive | Start as a Receiver | True"); + println!(" --debug | Start in Debug Mode | False"); + println!(" --help | Shows Help | False"); + println!("\n\n\n"); } fn main() { @@ -539,9 +537,12 @@ fn main() server:false, send:false, location:None, - debug:DebugMode::Off, + debug:false, }; - take_args(&mut user_environment); + if !take_args(&mut user_environment) + { + return; + } let mut file_info = FileInfo { file:None, @@ -555,13 +556,13 @@ fn main() { Connection::server (Connection::Server(user_environment.ip.to_string(), user_environment.port.to_string()), - &mut file_info, DebugMode::debug_mode(&user_environment.debug), &user_environment); + &mut file_info, &user_environment); }, false => { Connection::client (Connection::Client(user_environment.ip.to_string(), user_environment.port.to_string()), - &mut file_info, DebugMode::debug_mode(&user_environment.debug), &user_environment); + &mut file_info, &user_environment); } } } From a962fb83b6a4acd97d643ebd9ce443f06223ca5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20Kaan=20G=C3=9CM=C3=9C=C5=9E?= <96421894+Tahinli@users.noreply.github.com> Date: Mon, 30 Oct 2023 02:09:21 +0300 Subject: [PATCH 3/8] --- src/main.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index 5e60a3d..797d800 100644 --- a/src/main.rs +++ b/src/main.rs @@ -513,15 +513,15 @@ fn show_help() println!("\n\n\n"); println!(" Arguments | Details | Defaults"); println!("--------------------------------------------------------------"); - println!(" --ip | Specify IP Address | 127.0.0.1"); - println!(" --port | Specify Port Address | 2121"); - println!(" --location | Specify Location Address | Same as Program"); - println!(" --server | Start as a Server | False"); - println!(" --client | Start as a Client | True"); - println!(" --send | Start as a Sender | False"); - println!(" --receive | Start as a Receiver | True"); - println!(" --debug | Start in Debug Mode | False"); - println!(" --help | Shows Help | False"); + println!(" --ip | Specifies IP Address | 127.0.0.1"); + println!(" --port | Specifies Port Address | 2121"); + println!(" --location | Specifies Location Address | Same as Program"); + println!(" --server | Starts as a Server | False"); + println!(" --client | Starts as a Client | True"); + println!(" --send | Starts as a Sender | False"); + println!(" --receive | Starts as a Receiver | True"); + println!(" --debug | Starts in Debug Mode | False"); + println!(" --help | Shows Help | False"); println!("\n\n\n"); } fn main() From 217961e18b9cab15e67310d187dc2f7344b99d51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20Kaan=20G=C3=9CM=C3=9C=C5=9E?= <96421894+Tahinli@users.noreply.github.com> Date: Mon, 30 Oct 2023 13:22:43 +0300 Subject: [PATCH 4/8] feat: receiver folder specifiy --- src/main.rs | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/main.rs b/src/main.rs index 797d800..7b31b7a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -68,7 +68,7 @@ impl FileInfo } fn open_file(&mut self) { - match File::open(&self.location.as_ref().unwrap()) + match File::options().read(true).write(true).open(self.location.as_ref().unwrap()) { Ok(file) => { @@ -239,20 +239,26 @@ impl FileInfo } return Some(buffer); } - fn forge_file(&mut self) + fn forge_file(&mut self, location:String) { match &self.location { - Some(location) => + Some(self_location) => { - self.file = Some(File::create(&location).expect("Error: Create File")); + fs::create_dir_all(self_location).unwrap(); + let mut path = PathBuf::from(self_location); + path.push(&location); + self.location = Some(path.to_str().unwrap().to_string()); } None => { - println!("Error: Forge File -> {:#?}", self.location); - panic!(); + self.location = Some(location); } } + println!("{:#?}", self.location); + self.file = Some(File::create(self.location.as_ref().unwrap()).unwrap()); + println!("{:#?}", self.file); + self.open_file(); } fn callback_recv(&mut self, stream:&mut TcpStream, debug_mode:&bool) -> String { @@ -280,6 +286,7 @@ impl FileInfo fn save_exact(&mut self, buffer:&[u8], debug_mode:&bool) { let mut file_writer = BufWriter::new(self.file.as_ref().unwrap()); + println!("{:#?}", file_writer); match file_writer.write_all(buffer) { Ok(_) => @@ -315,8 +322,8 @@ impl FileInfo fn write_file(&mut self, stream:&mut TcpStream, debug_mode:&bool) { let size:u64 = self.callback_recv(stream, debug_mode).parse().unwrap(); - self.location = Some(self.callback_recv(stream, debug_mode)); - self.forge_file(); + let location:String = self.callback_recv(stream, debug_mode); + self.forge_file(location); let mut iteration:u64 = (size/BUFFER_SIZE)+1; let total_iteration = iteration; println!("File = {}", self.location.as_ref().unwrap()); From 0655c968d0e758a9324a8cd28791a9d5344c9b95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20Kaan=20G=C3=9CM=C3=9C=C5=9E?= <96421894+Tahinli@users.noreply.github.com> Date: Tue, 31 Oct 2023 02:53:42 +0300 Subject: [PATCH 5/8] feat: receiver receive files continuously perf: earlier exception detection refactor: some outputs refator: forge file --- src/main.rs | 183 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 140 insertions(+), 43 deletions(-) diff --git a/src/main.rs b/src/main.rs index 7b31b7a..811488e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,56 +23,97 @@ struct FileInfo { file:Option, location:Option, + sign:Option, size_current:usize, metadata:Option, + progress:u8, } impl FileInfo { fn reading_operations(&mut self, stream:&mut TcpStream, debug_mode:&bool) { - self.read_metadata(); - match self.metadata + //Pathbuf Symlink Metadata + //Pathbuf is_Symlink + match &self.location { - Some(ref mut metadata) => + Some(_) => { - if Metadata::is_file(metadata) + self.read_metadata(debug_mode); + match self.metadata { - self.open_file(); - self.send_file(stream, debug_mode); - } - else if Metadata::is_symlink(metadata) - { - self.open_file(); - self.send_file(stream, debug_mode); - } - else - { - //path recognition and creation on the other side - //std:path - panic!("\n\tError: Folder Transfers've not Supported yet\n") + Some(ref mut metadata) => + { + if Metadata::is_symlink(metadata) + { + //Recursivity Problem + println!("\n\tError: Symlink Transfers've not Supported yet\n"); + return; + } + else if Metadata::is_file(metadata) + { + self.open_file(debug_mode); + self.send_file(stream, debug_mode); + } + + else + { + //path recognition and creation on the other side + //std:path + println!("\n\tError: Folder Transfers've not Supported yet\n"); + return; + } + } + None => + { + println!("Error: Read Metadata -> {:#?}", &self.location); + } } } None => { - println!("Error: Read Metadata -> {}", self.location.as_ref().unwrap()); + println!("Error: Reading Operations -> {:#?}", &self.location); + panic!(); } } } fn writing_operations(&mut self, stream:&mut TcpStream, debug_mode:&bool) { self.write_file(stream, debug_mode); + self.clean_sign(); } - fn read_metadata(&mut self) + fn clean_sign(&mut self) { - self.metadata = Some(fs::metadata(&self.location.as_ref().unwrap()).expect("Error: Read Metadata")); + self.location = self.sign.clone(); } - fn open_file(&mut self) + fn read_metadata(&mut self, debug_mode:&bool) + { + match fs::metadata(&self.location.as_ref().unwrap()) + { + Ok(metadata) => + { + self.metadata = Some(metadata); + if *debug_mode + { + println!("Done: Read Metadata -> {:#?}", self.metadata); + } + } + Err(err_val) => + { + println!("Error: Read Metadata -> {} | Error: {}", &self.location.as_ref().unwrap(), err_val); + } + } + } + fn open_file(&mut self,debug_mode:&bool) { match File::options().read(true).write(true).open(self.location.as_ref().unwrap()) { Ok(file) => { self.file = Some(file); + if *debug_mode + { + println!("Done : Open File -> {:#?}", self.file); + } } Err(err_val) => { @@ -90,9 +131,7 @@ impl FileInfo let path_buf = PathBuf::from(Path::new(self.location.as_ref().unwrap())); self.callback_validation(stream, &(size.to_string()), debug_mode); self.callback_validation(stream, &path_buf.file_name().unwrap().to_str().unwrap().to_string(), debug_mode); - println!("File = {}", self.location.as_ref().unwrap()); - println!("Size = {}", size); - println!("Iteration = {}", iteration); + self.show_info(size, &iteration, debug_mode); while iteration != 0 { iteration -= 1; @@ -110,7 +149,7 @@ impl FileInfo println!("Read Data = {:#?}", buffer); } self.send_exact(&mut buffer, stream, debug_mode); - println!("%{}", 100 as f64 -((iteration as f64/total_iteration as f64)*100 as f64)); + self.show_progress(iteration, total_iteration); } } fn callback_validation(&mut self, stream:&mut TcpStream, data:&String, debug_mode:&bool) @@ -122,9 +161,9 @@ impl FileInfo { if callback_callback == data.to_string().as_bytes().to_vec() { - println!("Done: Callback -> {}", self.location.as_ref().unwrap()); if *debug_mode { + println!("Done: Callback -> {}", self.location.as_ref().unwrap()); println!("{:#?} ", callback_callback); } } @@ -239,26 +278,55 @@ impl FileInfo } return Some(buffer); } - fn forge_file(&mut self, location:String) + fn forge_file(&mut self, location:String, debug_mode:&bool) { - match &self.location + //dont forget + //directory recognition required for received location + match self.location.as_ref() { Some(self_location) => { - fs::create_dir_all(self_location).unwrap(); - let mut path = PathBuf::from(self_location); - path.push(&location); - self.location = Some(path.to_str().unwrap().to_string()); + let mut path = PathBuf::from(&self_location); + path.push(location); + self.forge_folder(self_location.clone(), debug_mode); + self.location = Some(path.to_str().unwrap().to_string()); } None => { self.location = Some(location); } } - println!("{:#?}", self.location); - self.file = Some(File::create(self.location.as_ref().unwrap()).unwrap()); - println!("{:#?}", self.file); - self.open_file(); + match File::create(self.location.as_ref().unwrap()) + { + Ok(file) => + { + if *debug_mode + { + println!("Done Forge File -> {:#?}", file); + } + } + Err(err_val) => + { + println!("Error: Forge File -> {:#?} | Error: {}", self.location.as_ref(), err_val); + } + } + } + fn forge_folder(&mut self, location:String, debug_mode:&bool) + { + match fs::create_dir_all(&location) + { + Ok(_) => + { + if *debug_mode + { + println!("Done: Forge Folder -> {}", &location); + } + } + Err(err_val) => + { + println!("Error: Forge Folder -> {} | Error: {}", location, err_val); + } + } } fn callback_recv(&mut self, stream:&mut TcpStream, debug_mode:&bool) -> String { @@ -266,9 +334,10 @@ impl FileInfo { Some(mut callback) => { - println!("Done: Callback -> {:#?}", self.location); + if *debug_mode { + println!("Done: Callback -> {:#?}", self.location); println!("{:#?} ", callback); } let data = String::from_utf8(callback.clone()).unwrap(); @@ -286,7 +355,10 @@ impl FileInfo fn save_exact(&mut self, buffer:&[u8], debug_mode:&bool) { let mut file_writer = BufWriter::new(self.file.as_ref().unwrap()); - println!("{:#?}", file_writer); + if *debug_mode + { + println!("{:#?}", file_writer); + } match file_writer.write_all(buffer) { Ok(_) => @@ -323,12 +395,11 @@ impl FileInfo { let size:u64 = self.callback_recv(stream, debug_mode).parse().unwrap(); let location:String = self.callback_recv(stream, debug_mode); - self.forge_file(location); + self.forge_file(location, debug_mode); + self.open_file(debug_mode); let mut iteration:u64 = (size/BUFFER_SIZE)+1; let total_iteration = iteration; - println!("File = {}", self.location.as_ref().unwrap()); - println!("Size = {}", size); - println!("Iteration = {}", iteration); + self.show_info(size, &iteration, debug_mode); while iteration != 0 { iteration -= 1; @@ -342,9 +413,31 @@ impl FileInfo { self.save_exact(&buffer[..(size%BUFFER_SIZE) as usize], debug_mode); } - println!("%{}", 100 as f64 -((iteration as f64/total_iteration as f64)*100 as f64)); + self.show_progress(iteration, total_iteration); } } + fn show_info(&mut self, size:u64, iteration:&u64, debug_mode:&bool) + { + println!("File = {}", self.location.as_ref().unwrap()); + println!("Size = {}", size); + if *debug_mode + { + println!("Iteration = {}", iteration); + } + } + fn show_progress(&mut self, iteration:u64, total_iteration:u64) + { + if iteration%10 == 0 + { + let progress:u8 = 100 as u8 - ((iteration as f64/total_iteration as f64)*100 as f64)as u8; + if progress != self.progress + { + self.progress = progress; + println!("%{}", self.progress); + } + } + + } } enum Connection { @@ -440,6 +533,7 @@ fn send_or_receive(file_info:&mut FileInfo, stream:&mut TcpStream, debug_mode:&b let start_time = Instant::now(); FileInfo::reading_operations(file_info, stream, &debug_mode); let finish_time = Instant::now(); + println!("Done: Transfer"); println!("Passed: Total -> {:#?}", finish_time.duration_since(start_time)); } false => @@ -447,6 +541,7 @@ fn send_or_receive(file_info:&mut FileInfo, stream:&mut TcpStream, debug_mode:&b let start_time = Instant::now(); FileInfo::writing_operations(file_info, stream, &debug_mode); let finish_time = Instant::now(); + println!("Done: Transfer"); println!("Passed: Total -> {:#?}", finish_time.duration_since(start_time)); } } @@ -554,8 +649,10 @@ fn main() { file:None, location:user_environment.location.clone(), + sign:user_environment.location.clone(), size_current:0 as usize, metadata:None, + progress:0, }; match user_environment.server { From 59c2997dc26db5ef0e3e21f5e76cc52880ee7879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20Kaan=20G=C3=9CM=C3=9C=C5=9E?= <96421894+Tahinli@users.noreply.github.com> Date: Tue, 31 Oct 2023 13:54:26 +0300 Subject: [PATCH 6/8] refactor: constructors refactor: user_environment refactor: file_info --- src/main.rs | 146 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 87 insertions(+), 59 deletions(-) diff --git a/src/main.rs b/src/main.rs index 811488e..ac828c1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,22 +18,57 @@ struct UserEnvironment location:Option, debug:bool, } +impl UserEnvironment + { + fn user_environment() -> UserEnvironment + { + UserEnvironment + { + ip:"127.0.0.1".parse().unwrap(), + port:2121, + server:false, + send:false, + location:None, + debug:false, + } + } + } #[derive(Debug)] struct FileInfo { file:Option, location:Option, sign:Option, - size_current:usize, + size_total:u64, + size_current:u64, metadata:Option, progress:u8, } impl FileInfo { + fn file_info() -> FileInfo + { + FileInfo + { + file: None, + location: None, + sign: None, + size_total: 0, + size_current: 0, + metadata: None, + progress: 0 + } + } + fn pass_user_environment(&mut self, user_environment:&UserEnvironment) + { + self.location = user_environment.location.clone(); + self.sign = user_environment.location.clone(); + } fn reading_operations(&mut self, stream:&mut TcpStream, debug_mode:&bool) { //Pathbuf Symlink Metadata - //Pathbuf is_Symlink + //Pathbuf is_Symlink + match &self.location { Some(_) => @@ -79,11 +114,12 @@ impl FileInfo fn writing_operations(&mut self, stream:&mut TcpStream, debug_mode:&bool) { self.write_file(stream, debug_mode); - self.clean_sign(); + self.cleaning(); } - fn clean_sign(&mut self) + fn cleaning(&mut self) { self.location = self.sign.clone(); + self.size_current = 0; } fn read_metadata(&mut self, debug_mode:&bool) { @@ -125,13 +161,13 @@ impl FileInfo } fn send_file(&mut self, stream:&mut TcpStream, debug_mode:&bool) { - let size = self.metadata.as_ref().unwrap().len(); - let mut iteration = (size/BUFFER_SIZE)+1; + self.size_total = self.metadata.as_ref().unwrap().len(); + let mut iteration = (self.size_total/BUFFER_SIZE)+1; let total_iteration = iteration; let path_buf = PathBuf::from(Path::new(self.location.as_ref().unwrap())); - self.callback_validation(stream, &(size.to_string()), debug_mode); + self.callback_validation(stream, &(self.size_total.to_string()), debug_mode); self.callback_validation(stream, &path_buf.file_name().unwrap().to_str().unwrap().to_string(), debug_mode); - self.show_info(size, &iteration, debug_mode); + self.show_info(&iteration, debug_mode); while iteration != 0 { iteration -= 1; @@ -142,7 +178,7 @@ impl FileInfo } else { - self.read_exact(&mut buffer[..(size%BUFFER_SIZE) as usize], debug_mode); + self.read_exact(&mut buffer[..(self.size_total%BUFFER_SIZE) as usize], debug_mode); } if *debug_mode { @@ -206,7 +242,7 @@ impl FileInfo { Ok(_) => { - self.size_current += buffer.len(); + self.size_current += buffer.len() as u64; if *debug_mode { println!("Done: Send Bytes -> {:#?}", self.location); @@ -241,7 +277,7 @@ impl FileInfo { Ok(_) => { - self.size_current += buffer.len(); + self.size_current += buffer.len() as u64; if *debug_mode { println!("Done: Receive Bytes -> {:#?}", self.location); @@ -399,7 +435,7 @@ impl FileInfo self.open_file(debug_mode); let mut iteration:u64 = (size/BUFFER_SIZE)+1; let total_iteration = iteration; - self.show_info(size, &iteration, debug_mode); + self.show_info(&iteration, debug_mode); while iteration != 0 { iteration -= 1; @@ -416,10 +452,10 @@ impl FileInfo self.show_progress(iteration, total_iteration); } } - fn show_info(&mut self, size:u64, iteration:&u64, debug_mode:&bool) + fn show_info(&mut self, iteration:&u64, debug_mode:&bool) { println!("File = {}", self.location.as_ref().unwrap()); - println!("Size = {}", size); + println!("Size = {}", self.size_total); if *debug_mode { println!("Iteration = {}", iteration); @@ -546,84 +582,84 @@ fn send_or_receive(file_info:&mut FileInfo, stream:&mut TcpStream, debug_mode:&b } } } -fn take_args(user_environment:&mut UserEnvironment) -> bool +fn take_args(mut user_environment:UserEnvironment) -> Option { let env_args:Vec = env::args().collect(); if env_args.len() > 16 { println!("Error: Too Many Arguments, You Gave {} Arguments", env_args.len()); - return false; + return None; } let mut i = 1; while i < env_args.len() { match env_args[i].as_str() { - "--ip" => + "--ip" | "-i" => { user_environment.ip = env_args[i+1].parse().unwrap(); i += 1; } - "--port" => + "--port" | "-p" => { user_environment.port = env_args[i+1].parse().unwrap(); i += 1; } - "--location" => + "--location" | "-l" => { user_environment.location = Some(env_args[i+1].parse().unwrap()); i += 1; } - "--server" => + "--server"| "-sv" => { user_environment.server = true; } - "--client" => + "--client" | "-cl" => { user_environment.server = false; } - "--send" => + "--send" | "-s" => { user_environment.send = true; } - "--receive" => + "--receive" | "-r" => { user_environment.send = false; } - "--debug" => + "--debug" | "-d" => { user_environment.debug = false; } - "--help" => + "--help" | "-h" => { show_help(); - return false; + return None; } err => { println!("Error: Invalid Argument, You Gave {}", err); - return false; + return None; } } i += 1; } - true + Some(user_environment) } fn show_help() { println!("\n\n\n"); - println!(" Arguments | Details | Defaults"); - println!("--------------------------------------------------------------"); - println!(" --ip | Specifies IP Address | 127.0.0.1"); - println!(" --port | Specifies Port Address | 2121"); - println!(" --location | Specifies Location Address | Same as Program"); - println!(" --server | Starts as a Server | False"); - println!(" --client | Starts as a Client | True"); - println!(" --send | Starts as a Sender | False"); - println!(" --receive | Starts as a Receiver | True"); - println!(" --debug | Starts in Debug Mode | False"); - println!(" --help | Shows Help | False"); + println!(" Arguments | Details | Defaults"); + println!("----------------------------------------------------------------------"); + println!(" -i -> --ip | Specifies IP Address | 127.0.0.1"); + println!(" -p -> --port | Specifies Port Address | 2121"); + println!(" -l -> --location | Specifies Location Address | Same as Program"); + println!(" -sv -> --server | Starts as a Server | False"); + println!(" -cl -> --client | Starts as a Client | True"); + println!(" -s -> --send | Starts as a Sender | False"); + println!(" -r -> --receive | Starts as a Receiver | True"); + println!(" -d -> --debug | Starts in Debug Mode | False"); + println!(" -h -> --help | Shows Help | False"); println!("\n\n\n"); } fn main() @@ -632,28 +668,20 @@ fn main() //First we should check folder structure and validation then make connection. //Until's can be deprecated, 100k byte should be enough for eveything.(Security) println!("Hello, world!"); - let mut user_environment = UserEnvironment + let mut file_info:FileInfo = FileInfo::file_info(); + let user_environment:UserEnvironment; + match take_args(UserEnvironment::user_environment()) { - ip:"127.0.0.1".parse().unwrap(), - port:2121, - server:false, - send:false, - location:None, - debug:false, - }; - if !take_args(&mut user_environment) - { - return; + Some(usr_env) => + { + user_environment = usr_env; + } + None => + { + return; + } } - let mut file_info = FileInfo - { - file:None, - location:user_environment.location.clone(), - sign:user_environment.location.clone(), - size_current:0 as usize, - metadata:None, - progress:0, - }; + file_info.pass_user_environment(&user_environment); match user_environment.server { true => From ccc2dbc547bd748ecf5141d0b24b67acd73c7640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20Kaan=20G=C3=9CM=C3=9C=C5=9E?= <96421894+Tahinli@users.noreply.github.com> Date: Sat, 4 Nov 2023 20:59:16 +0300 Subject: [PATCH 7/8] fix: Symlink Detection --- src/main.rs | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/src/main.rs b/src/main.rs index ac828c1..d4fcedb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -82,7 +82,9 @@ impl FileInfo { //Recursivity Problem println!("\n\tError: Symlink Transfers've not Supported yet\n"); - return; + //return; + self.open_file(debug_mode); + self.send_file(stream, debug_mode); } else if Metadata::is_file(metadata) { @@ -123,19 +125,37 @@ impl FileInfo } fn read_metadata(&mut self, debug_mode:&bool) { - match fs::metadata(&self.location.as_ref().unwrap()) + let path = PathBuf::from(self.location.as_ref().unwrap()); + if path.is_symlink() { - Ok(metadata) => + match path.symlink_metadata() { - self.metadata = Some(metadata); - if *debug_mode + Ok(metadata) => { - println!("Done: Read Metadata -> {:#?}", self.metadata); + self.metadata = Some(metadata); + } + Err(err_val) => + { + println!("Error: Symlink Metadata -> {:#?} | Error: {}", &self.location, err_val); } } - Err(err_val) => + } + else + { + match fs::metadata(&self.location.as_ref().unwrap()) { - println!("Error: Read Metadata -> {} | Error: {}", &self.location.as_ref().unwrap(), err_val); + Ok(metadata) => + { + self.metadata = Some(metadata); + if *debug_mode + { + println!("Done: Read Metadata -> {:#?}", self.metadata); + } + } + Err(err_val) => + { + println!("Error: Read Metadata -> {} | Error: {}", &self.location.as_ref().unwrap(), err_val); + } } } } From 0a6a1efc5f614bf8e27ec903d59969d5b62fb70b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20Kaan=20G=C3=9CM=C3=9C=C5=9E?= <96421894+Tahinli@users.noreply.github.com> Date: Mon, 6 Nov 2023 02:44:17 +0300 Subject: [PATCH 8/8] feat: file type recognition on the receiver --- src/main.rs | 105 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 88 insertions(+), 17 deletions(-) diff --git a/src/main.rs b/src/main.rs index d4fcedb..46715db 100644 --- a/src/main.rs +++ b/src/main.rs @@ -66,10 +66,7 @@ impl FileInfo } fn reading_operations(&mut self, stream:&mut TcpStream, debug_mode:&bool) { - //Pathbuf Symlink Metadata - //Pathbuf is_Symlink - - match &self.location + match self.location.as_ref() { Some(_) => { @@ -80,29 +77,35 @@ impl FileInfo { if Metadata::is_symlink(metadata) { - //Recursivity Problem + //Unix-Windows Problem println!("\n\tError: Symlink Transfers've not Supported yet\n"); - //return; - self.open_file(debug_mode); - self.send_file(stream, debug_mode); + return; + //self.open_file(debug_mode); + //self.send_file(stream, &(100 as u8),debug_mode); } else if Metadata::is_file(metadata) { self.open_file(debug_mode); - self.send_file(stream, debug_mode); + self.send_file(stream, &(101 as u8),debug_mode); } - else + else if Metadata::is_dir(metadata) { //path recognition and creation on the other side //std:path println!("\n\tError: Folder Transfers've not Supported yet\n"); return; + //self.open_file(debug_mode); + //self.send_file(stream, &(102 as u8),debug_mode); + } + else + { + println!("Error: Undefined Type -> {}", self.location.as_ref().unwrap()); } } None => { - println!("Error: Read Metadata -> {:#?}", &self.location); + println!("Error: Read Metadata -> {}", self.location.as_ref().unwrap()); } } } @@ -179,14 +182,49 @@ impl FileInfo } } - fn send_file(&mut self, stream:&mut TcpStream, debug_mode:&bool) + fn send_file(&mut self, stream:&mut TcpStream, what_type:&u8,debug_mode:&bool) { self.size_total = self.metadata.as_ref().unwrap().len(); let mut iteration = (self.size_total/BUFFER_SIZE)+1; let total_iteration = iteration; let path_buf = PathBuf::from(Path::new(self.location.as_ref().unwrap())); + match what_type + { + 100 => + { + if *debug_mode + { + println!("Done: Symlink Detected -> {}", self.location.as_ref().unwrap()); + } + self.callback_validation(stream, &String::from("100"), debug_mode); + } + 101 => + { + if *debug_mode + { + println!("Done: File Detected -> {}", self.location.as_ref().unwrap()); + } + self.callback_validation(stream, &String::from("101"), debug_mode) + } + 102 => + { + if *debug_mode + { + println!("Done: Folder Detected -> {}", self.location.as_ref().unwrap()); + } + self.callback_validation(stream, &String::from("102"), debug_mode) + } + _ => + { + + println!("Error: Undefined Type Detected ->{}", self.location.as_ref().unwrap()); + return; + + } + } self.callback_validation(stream, &(self.size_total.to_string()), debug_mode); self.callback_validation(stream, &path_buf.file_name().unwrap().to_str().unwrap().to_string(), debug_mode); + self.show_info(&iteration, debug_mode); while iteration != 0 { @@ -449,11 +487,44 @@ impl FileInfo } fn write_file(&mut self, stream:&mut TcpStream, debug_mode:&bool) { - let size:u64 = self.callback_recv(stream, debug_mode).parse().unwrap(); + let what_type:u8 = self.callback_recv(stream, debug_mode).parse().unwrap(); + self.size_total = self.callback_recv(stream, debug_mode).parse().unwrap(); let location:String = self.callback_recv(stream, debug_mode); - self.forge_file(location, debug_mode); + match what_type + { + 100 => + { + if *debug_mode + { + println!("Done: Symlink Detected -> {}", self.location.as_ref().unwrap()); + } + self.forge_file( location, debug_mode); + return; + } + 101 => + { + if *debug_mode + { + println!("Done: File Detected -> {}", self.location.as_ref().unwrap()); + } + self.forge_file(location, debug_mode); + } + 102 => + { + if *debug_mode + { + println!("Done: Folder Detected -> {}", self.location.as_ref().unwrap()); + } + self.forge_file(location, debug_mode); + } + _ => + { + println!("Error: Undefined Type -> {}", self.location.as_ref().unwrap()); + return; + } + } self.open_file(debug_mode); - let mut iteration:u64 = (size/BUFFER_SIZE)+1; + let mut iteration:u64 = (&self.size_total/BUFFER_SIZE)+1; let total_iteration = iteration; self.show_info(&iteration, debug_mode); while iteration != 0 @@ -467,7 +538,7 @@ impl FileInfo } else { - self.save_exact(&buffer[..(size%BUFFER_SIZE) as usize], debug_mode); + self.save_exact(&buffer[..(&self.size_total%BUFFER_SIZE) as usize], debug_mode); } self.show_progress(iteration, total_iteration); } @@ -648,7 +719,7 @@ fn take_args(mut user_environment:UserEnvironment) -> Option } "--debug" | "-d" => { - user_environment.debug = false; + user_environment.debug = true; } "--help" | "-h" => {