diff --git a/Cargo.lock b/Cargo.lock index c1540d6..545a5c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + [[package]] name = "bitflags" version = "1.3.2" @@ -109,6 +115,12 @@ dependencies = [ "slab", ] +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -118,6 +130,16 @@ dependencies = [ "libc", ] +[[package]] +name = "indexmap" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +dependencies = [ + "autocfg", + "hashbrown", +] + [[package]] name = "itoa" version = "1.0.1" @@ -130,6 +152,12 @@ version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f" +[[package]] +name = "linked-hash-map" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" + [[package]] name = "lock_api" version = "0.4.6" @@ -266,11 +294,13 @@ dependencies = [ [[package]] name = "rustocat" -version = "0.0.2" +version = "0.0.3" dependencies = [ "futures", "serde", "serde_json", + "serde_yaml", + "simple-error", "tokio", ] @@ -317,6 +347,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_yaml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a521f2940385c165a24ee286aa8599633d162077a54bdcae2a6fd5a7bfa7a0" +dependencies = [ + "indexmap", + "ryu", + "serde", + "yaml-rust", +] + [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -326,6 +368,12 @@ dependencies = [ "libc", ] +[[package]] +name = "simple-error" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc47a29ce97772ca5c927f75bac34866b16d64e07f330c3248e2d7226623901b" + [[package]] name = "slab" version = "0.4.5" @@ -466,3 +514,12 @@ name = "windows_x86_64_msvc" version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] diff --git a/Cargo.toml b/Cargo.toml index 2982e15..3ceb556 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustocat" -version = "0.0.2" +version = "0.0.3" edition = "2021" description = "Socat in rust with many less features and a configuration file" license = "ISC" @@ -12,7 +12,8 @@ tokio = { version = "1.17.0", features = ["full"] } futures = "0.3.21" serde = { version = "1.0.136", features = ["derive"] } serde_json = "1.0.79" - +serde_yaml = "0.8.23" +simple-error = "0.2.3" [profile.release] opt-level = 'z' # Optimize for size. diff --git a/README.md b/README.md new file mode 100644 index 0000000..5d0d3b2 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# Rustocat + +Rustocat is a simple socat alternative with way less features, but it has a config file. + +## Config File + +Configs can be either yaml or json and can be located in /etc/rustocat.{yaml|json} or ind the current working directory as config.{yaml|json}. + +```yaml +tcp: + - source: 0.0.0.0:2222 + target: 127.0.0.1:22 +``` + +Currently only TCP is supported, UDP/Unix Socket support might be added later. diff --git a/src/main.rs b/src/main.rs index e85d1bc..853f82e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,8 @@ mod shutdown; mod tcp; use serde::Deserialize; +use simple_error::bail; +use std::error::Error; use std::fs::File; use std::path::Path; use tokio::sync::broadcast; @@ -19,14 +21,48 @@ struct Config { // udp: Vec, } +fn load_yaml(path: &Path) -> Result> { + let file = File::open(path)?; + let config: Config = serde_yaml::from_reader(file).expect("Failed to parse!"); //TODO: Print path + + return Ok(config); +} + +fn load_json(path: &Path) -> Result> { + let file = File::open(path)?; + let config: Config = serde_json::from_reader(file).expect("Failed to parse!"); //TODO: Print path + + return Ok(config); +} + +fn load_config() -> Result> { + for path in [ + "config.yaml", + "config.json", + "/etc/rustocat.yaml", + "/etc/rustocat.json", + ] + .iter() + { + // if(p) + let config = if path.ends_with(".yaml") { + load_yaml(Path::new(path)) + } else { + load_json(Path::new(path)) + }; + if config.is_ok() { + return config; + } + } + bail!("No config file found"); +} + #[tokio::main] async fn main() { - let json_file_path = Path::new("./config.json"); - let file = File::open(json_file_path).expect("file not found"); + let config = load_config().expect("config not found"); let (notify_shutdown, _) = broadcast::channel(1); - let config: Config = serde_json::from_reader(file).expect("json parse error"); for target in config.tcp { let listener = listener::Listener { shutdown: shutdown::Shutdown::new(notify_shutdown.subscribe()), diff --git a/src/shutdown.rs b/src/shutdown.rs index def495d..b871005 100644 --- a/src/shutdown.rs +++ b/src/shutdown.rs @@ -28,9 +28,9 @@ impl Shutdown { } /// Returns `true` if the shutdown signal has been received. - pub(crate) fn is_shutdown(&self) -> bool { - self.shutdown - } + // pub(crate) fn is_shutdown(&self) -> bool { + // self.shutdown + // } /// Receive the shutdown notice, waiting if necessary. pub(crate) async fn recv(&mut self) {