diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml index 3c28b72..be0b511 100644 --- a/.github/workflows/unit.yml +++ b/.github/workflows/unit.yml @@ -17,5 +17,9 @@ jobs: - uses: actions/checkout@v3 - name: Build run: cargo build --verbose + - name: Build + run: cargo build --features client --verbose - name: Run tests run: cargo test --verbose + - name: test client + run: cargo test --features client --verbose diff --git a/Cargo.toml b/Cargo.toml index 2e8e0ee..745f713 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,15 @@ license = "MIT" keywords = ["tftp", "server"] categories = ["command-line-utilities"] +[[bin]] +name = "tftpc" +path = "src/client_main.rs" +required-features = ["client"] + +[[bin]] +name = "tftpd" +path = "src/main.rs" + [features] integration = [] client = [] \ No newline at end of file diff --git a/README.md b/README.md index da469c0..5860600 100644 --- a/README.md +++ b/README.md @@ -34,28 +34,22 @@ tftpd -i 0.0.0.0 -p 1234 -d "/home/user/tftp" -r ## Usage (Client) +Client code is protected by a feature flag names `client`. To install the client and server using Cargo: ```bash cargo install --features client tftpd -tftpd client --help -tftpd server --help -``` - -To run the server on the IP address `0.0.0.0`, read-only, on port `1234` in the `/home/user/tftp` directory: - -```bash -tftpd server -i 0.0.0.0 -p 1234 -d "/home/user/tftp" -r +tftpc --help ``` To connect the client to a tftp server running on IP address `127.0.0.1`, read-only, on port `1234` and download a file named `example.file` ```bash -tftpd client example.file -i 0.0.0.0 -p 1234 -d +tftpc example.file -i 0.0.0.0 -p 1234 -d ``` To connect the client to a tftp server running on IP address `127.0.0.1`, read-only, on port `1234` and upload a file named `example.file` ```bash -tftpd client ./example.file -i 0.0.0.0 -p 1234 -u +tftpc ./example.file -i 0.0.0.0 -p 1234 -u ``` ## License diff --git a/src/client.rs b/src/client.rs index b404ed9..4d0a385 100644 --- a/src/client.rs +++ b/src/client.rs @@ -55,8 +55,8 @@ impl Client { }) } - /// Starts the Client depending on the [`Mode`] the client is in - pub fn start(&mut self) -> Result<(), Box> { + /// Run the Client depending on the [`Mode`] the client is in + pub fn run(&mut self) -> Result<(), Box> { match self.mode { Mode::Upload => self.upload(), Mode::Download => self.download(), diff --git a/src/client_main.rs b/src/client_main.rs new file mode 100644 index 0000000..d6d2a77 --- /dev/null +++ b/src/client_main.rs @@ -0,0 +1,39 @@ +use std::error::Error; +use std::env::args; +use std::{env, net::SocketAddr, process}; +use tftpd::{Client, ClientConfig, Config, Mode, Server}; + +fn main() { + let args: Vec = env::args().collect(); + client(args[0..].iter().map(|s| s.to_string())).unwrap_or_else(|err| { + eprintln!("{err}"); + }) +} + +fn client>(args: T) -> Result<(), Box> { + let config = ClientConfig::new(args).unwrap_or_else(|err| { + eprintln!("Problem parsing arguments: {err}"); + process::exit(1) + }); + + let mut client = Client::new(&config).unwrap_or_else(|err| { + eprintln!("Problem creating client: {err}"); + process::exit(1) + }); + + if config.mode == Mode::Upload { + println!( + "Starting TFTP Client, uploading {} to {}", + config.filename.display(), + SocketAddr::new(config.remote_ip_address, config.port), + ); + } else { + println!( + "Starting TFTP Client, downloading {} to {}", + config.filename.display(), + SocketAddr::new(config.remote_ip_address, config.port), + ); + } + + client.run() +} diff --git a/src/main.rs b/src/main.rs index ffa04d0..581c7e7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,65 +1,11 @@ -#[cfg(feature = "client")] -use std::error::Error; use std::{env, net::SocketAddr, process}; -#[cfg(not(feature = "client"))] use tftpd::{Config, Server}; -#[cfg(feature = "client")] -use tftpd::{Client, ClientConfig, Config, Mode, Server}; -#[cfg(feature = "client")] -fn main() { - let args: Vec = env::args().collect(); - if args.len() < 2 { - eprintln!("{}: incorrect usage", args[0]); - eprintln!("{} [args]", args[0]); - } else if args[1] == "client" { - client(args[1..].iter().map(|s| s.to_string())).unwrap_or_else(|err| { - eprintln!("{err}"); - }) - } else if args[1] == "server" { - server(args[1..].iter().map(|s| s.to_string())); - } else { - eprintln!("{}: incorrect usage", args[0]); - eprintln!("{} (client | server) [args]", args[0]); - } -} - - -#[cfg(not(feature = "client"))] fn main() { let args: Vec = env::args().collect(); server(args[0..].iter().map(|s| s.to_string())); } -#[cfg(feature = "client")] -fn client>(args: T) -> Result<(), Box> { - let config = ClientConfig::new(args).unwrap_or_else(|err| { - eprintln!("Problem parsing arguments: {err}"); - process::exit(1) - }); - - let mut server = Client::new(&config).unwrap_or_else(|err| { - eprintln!("Problem creating client: {err}"); - process::exit(1) - }); - - if config.mode == Mode::Upload { - println!( - "Starting TFTP Client, uploading {} to {}", - config.filename.display(), - SocketAddr::new(config.remote_ip_address, config.port), - ); - } else { - println!( - "Starting TFTP Client, downloading {} to {}", - config.filename.display(), - SocketAddr::new(config.remote_ip_address, config.port), - ); - } - - server.start() -} - fn server>(args: T) { let config = Config::new(args).unwrap_or_else(|err| { eprintln!("Problem parsing arguments: {err}");