Skip to content

Commit

Permalink
feat: make cli option to prevent file removal after receiving errors.…
Browse files Browse the repository at this point in the history
… integrate option into Config & ClientConfig and populate to Worker applying required behavior
  • Loading branch information
mykola2312 committed Jul 17, 2024
1 parent b9264c8 commit de0e790
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub struct Client {
mode: Mode,
filename: PathBuf,
save_path: PathBuf,
clean_on_error: bool
}

/// Enum used to set the client either in Download Mode or Upload Mode
Expand All @@ -52,6 +53,7 @@ impl Client {
mode: config.mode,
filename: config.filename.clone(),
save_path: config.receive_directory.clone(),
clean_on_error: config.clean_on_error
})
}

Expand Down Expand Up @@ -240,6 +242,7 @@ impl Client {
Worker::new(
socket,
file,
self.clean_on_error,
self.blocksize,
DEFAULT_TIMEOUT,
self.windowsize,
Expand All @@ -249,6 +252,7 @@ impl Client {
Worker::new(
socket,
PathBuf::from(self.filename.clone()),
self.clean_on_error,
self.blocksize,
DEFAULT_TIMEOUT,
self.windowsize,
Expand Down
9 changes: 9 additions & 0 deletions src/client_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ pub struct ClientConfig {
pub receive_directory: PathBuf,
/// File to Upload or Download.
pub filename: PathBuf,
/// Should clean (delete) files after receiving errors. (default: true)
pub clean_on_error: bool
}

impl Default for ClientConfig {
Expand All @@ -52,6 +54,7 @@ impl Default for ClientConfig {
mode: Mode::Download,
receive_directory: Default::default(),
filename: Default::default(),
clean_on_error: true
}
}
}
Expand Down Expand Up @@ -116,6 +119,9 @@ impl ClientConfig {
"-d" | "--download" => {
config.mode = Mode::Download;
}
"--dont-clean" => {
config.clean_on_error = false;
}
"-h" | "--help" => {
println!("TFTP Client\n");
println!("Usage: tftpd client <File> [OPTIONS]\n");
Expand All @@ -130,6 +136,7 @@ impl ClientConfig {
println!(" -u, --upload\t\t\t\tSets the client to upload mode, Ignores all previous download flags");
println!(" -d, --download\t\t\tSet the client to download mode, Invalidates all previous upload flags");
println!(" -rd, --receive-directory <DIRECTORY>\tSet the directory to receive files when in Download mode (default: current working directory)");
println!(" --dont-clean\t\t\t\tWill prevent client from deleting files after receiving errors.");
println!(" -h, --help\t\t\t\tPrint help information");
process::exit(0);
}
Expand Down Expand Up @@ -169,6 +176,7 @@ mod tests {
"2",
"-t",
"4",
"--dont-clean"
]
.iter()
.map(|s| s.to_string()),
Expand All @@ -183,6 +191,7 @@ mod tests {
assert_eq!(config.blocksize, 1024);
assert_eq!(config.mode, Mode::Upload);
assert_eq!(config.timeout, Duration::from_secs(4));
assert_eq!(config.clean_on_error, false);
}

#[test]
Expand Down
10 changes: 9 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ pub struct Config {
pub duplicate_packets: u8,
/// Overwrite existing files. (default: false)
pub overwrite: bool,
/// Should clean (delete) files after receiving errors. (default: true)
pub clean_on_error: bool
}

impl Default for Config {
Expand All @@ -51,6 +53,7 @@ impl Default for Config {
read_only: Default::default(),
duplicate_packets: Default::default(),
overwrite: Default::default(),
clean_on_error: true
}
}
}
Expand Down Expand Up @@ -131,6 +134,7 @@ impl Config {
println!(" -r, --read-only\t\t\tRefuse all write requests, making the server read-only (default: false)");
println!(" --duplicate-packets <NUM>\t\tDuplicate all packets sent from the server (default: 0)");
println!(" --overwrite\t\t\t\tOverwrite existing files (default: false)");
println!(" --dont-clean\t\t\t\tWill prevent daemon from deleting files after receiving errors.");
println!(" -h, --help\t\t\t\tPrint help information");
process::exit(0);
}
Expand All @@ -153,6 +157,9 @@ impl Config {
"--overwrite" => {
config.overwrite = true;
}
"--dont-clean" => {
config.clean_on_error = false;
}

invalid => return Err(format!("Invalid flag: {invalid}").into()),
}
Expand All @@ -179,7 +186,7 @@ mod tests {
fn parses_full_config() {
let config = Config::new(
[
"/", "-i", "0.0.0.0", "-p", "1234", "-d", "/", "-rd", "/", "-sd", "/", "-s", "-r",
"/", "-i", "0.0.0.0", "-p", "1234", "-d", "/", "-rd", "/", "-sd", "/", "-s", "-r", "--dont-clean"
]
.iter()
.map(|s| s.to_string()),
Expand All @@ -191,6 +198,7 @@ mod tests {
assert_eq!(config.directory, PathBuf::from("/"));
assert_eq!(config.receive_directory, PathBuf::from("/"));
assert_eq!(config.send_directory, PathBuf::from("/"));
assert_eq!(config.clean_on_error, false);
assert!(config.single_port);
assert!(config.read_only);
}
Expand Down
4 changes: 4 additions & 0 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub struct Server {
single_port: bool,
read_only: bool,
overwrite: bool,
clean_on_error: bool,
duplicate_packets: u8,
largest_block_size: usize,
clients: HashMap<SocketAddr, Sender<Packet>>,
Expand All @@ -50,6 +51,7 @@ impl Server {
single_port: config.single_port,
read_only: config.read_only,
overwrite: config.overwrite,
clean_on_error: config.clean_on_error,
duplicate_packets: config.duplicate_packets,
largest_block_size: DEFAULT_BLOCK_SIZE,
clients: HashMap::new(),
Expand Down Expand Up @@ -179,6 +181,7 @@ impl Server {
let worker = Worker::new(
socket,
file_path.clone(),
self.clean_on_error,
worker_options.block_size,
worker_options.timeout,
worker_options.window_size,
Expand Down Expand Up @@ -220,6 +223,7 @@ impl Server {
let worker = Worker::new(
socket,
file_path.clone(),
self.clean_on_error,
worker_options.block_size,
worker_options.timeout,
worker_options.window_size,
Expand Down
11 changes: 9 additions & 2 deletions src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const DEFAULT_DUPLICATE_DELAY: Duration = Duration::from_millis(1);
/// let worker = Worker::new(
/// Box::new(socket),
/// PathBuf::from_str("Cargo.toml").unwrap(),
/// true,
/// 512,
/// Duration::from_secs(1),
/// 1,
Expand All @@ -43,6 +44,7 @@ const DEFAULT_DUPLICATE_DELAY: Duration = Duration::from_millis(1);
pub struct Worker<T: Socket + ?Sized> {
socket: Box<T>,
file_name: PathBuf,
clean_on_error: bool,
blk_size: usize,
timeout: Duration,
windowsize: u16,
Expand All @@ -54,6 +56,7 @@ impl<T: Socket + ?Sized> Worker<T> {
pub fn new(
socket: Box<T>,
file_name: PathBuf,
clean_on_error: bool,
blk_size: usize,
timeout: Duration,
windowsize: u16,
Expand All @@ -62,6 +65,7 @@ impl<T: Socket + ?Sized> Worker<T> {
Worker {
socket,
file_name,
clean_on_error,
blk_size,
timeout,
windowsize,
Expand Down Expand Up @@ -102,6 +106,7 @@ impl<T: Socket + ?Sized> Worker<T> {
/// Receives a file from the remote [`SocketAddr`] that has sent a write request using
/// the supplied socket, asynchronously.
pub fn receive(self) -> Result<JoinHandle<()>, Box<dyn Error>> {
let clean_on_error = self.clean_on_error;
let file_name = self.file_name.clone();
let remote_addr = self.socket.remote_addr().unwrap();

Expand All @@ -122,8 +127,10 @@ impl<T: Socket + ?Sized> Worker<T> {
}
Err(err) => {
eprintln!("{err}");
if fs::remove_file(&file_name).is_err() {
eprintln!("Error while cleaning {}", &file_name.to_str().unwrap());
if clean_on_error {
if fs::remove_file(&file_name).is_err() {
eprintln!("Error while cleaning {}", &file_name.to_str().unwrap());
}
}
}
}
Expand Down

0 comments on commit de0e790

Please sign in to comment.