diff --git a/Cargo.lock b/Cargo.lock index dcad2b1..cdcf7ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -519,7 +519,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "updns" -version = "0.0.1" +version = "0.0.2" dependencies = [ "ace 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "async-std 0.99.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 044078c..9d8b9bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "updns" -version = "0.0.1" +version = "0.0.2" edition = "2018" authors = ["wyhaya "] diff --git a/README.md b/README.md index 9985991..16a1bce 100644 --- a/README.md +++ b/README.md @@ -60,12 +60,12 @@ docker build -t updns . Start up ```bash -docker run -d --name updns -p 53:53/udp --restart always updns +docker run -d --name updns -p 53:53/udp -v /root/updns/:/root/.updns/ --restart always updns ``` ## Config -You can use `updns config` command and then call `vim` quick edit, or use `updns path` find the updns's installation directory and edit the `.updns` file +You can use `updns config` command and then call `vim` quick edit, or use `updns path` find the updns's installation directory and edit the `config` file You can specify standard domains, or utilize [regular expressions](https://rustexp.lpil.uk "rustexp") for dynamic matching, You can update the config file at any time, updns will listen for file changes diff --git a/src/config.rs b/src/config.rs index 72a7f73..5a9b868 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,9 +1,10 @@ use regex::Regex; +use std::fs; use std::fs::File; use std::io; use std::io::{Read, Write}; use std::net::{IpAddr, SocketAddr}; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::slice::Iter; lazy_static! { @@ -12,7 +13,7 @@ lazy_static! { static ref REG_PROXY: Regex = Regex::new(r#"^\s*proxy\s+(?P[^\s#]+)"#).unwrap(); // todo // The path will also contain '#' and ' ' - static ref REG_IMPORT: Regex = Regex::new(r#"\s*import\s+(?P(/.*))"#).unwrap(); + static ref REG_IMPORT: Regex = Regex::new(r#"^\s*import\s+(?P(.*))$"#).unwrap(); static ref REG_DOMAIN_IP: Regex = Regex::new(r#"^\s*(?P[^\s#]+)\s+(?P[^\s#]+)"#).unwrap(); } @@ -68,6 +69,7 @@ fn cap_ip_addr(text: &str) -> Option> { #[derive(Debug)] pub struct Config { + path: PathBuf, file: File, content: String, } @@ -89,7 +91,12 @@ pub enum InvalidType { impl Config { pub fn new>(path: P) -> io::Result { - let mut file = std::fs::OpenOptions::new() + let path = path.as_ref(); + + if let Some(dir) = path.parent() { + fs::create_dir_all(dir)?; + } + let mut file = fs::OpenOptions::new() .read(true) .append(true) .create(true) @@ -98,7 +105,11 @@ impl Config { let mut content = String::new(); file.read_to_string(&mut content)?; - Ok(Config { file, content }) + Ok(Config { + file, + content, + path: path.to_path_buf(), + }) } pub fn add(&mut self, domain: &str, ip: &str) -> std::io::Result<()> { @@ -154,7 +165,15 @@ impl Config { // import if let Some(cap) = REG_IMPORT.captures(&line) { if let Some(m) = cap.name("val") { - let (b, p, h, e) = Config::new(m.as_str())?.parse()?; + let mut p = Path::new(m.as_str()).to_path_buf(); + + if p.is_relative() { + if let Some(parent) = self.path.parent() { + p = parent.join(p); + } + } + + let (b, p, h, e) = Config::new(p)?.parse()?; binds.extend(b); proxy.extend(p); hosts.extend(h); diff --git a/src/main.rs b/src/main.rs index 0a5c8c0..1a6dd85 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,7 +22,7 @@ use std::process::Command; use std::time::Duration; use watch::Watch; -const CONFIG_NAME: &str = ".updns"; +const CONFIG_NAME: &str = ".updns/config"; const DEFAULT_BIND: &str = "0.0.0.0:53"; const DEFAULT_PROXY: [&str; 2] = ["8.8.8.8:53", "114.114.114.114:53"]; const PROXY_TIMEOUT: u64 = 2000; @@ -149,7 +149,11 @@ fn main() { Ok(p) => p.display().to_string(), Err(err) => exit!("Failed to get directory\n{:?}", err), }; - log!("Binary: {}\nConfig: {:?}", binary, config_path); + log!( + "Binary: {}\nConfig: {}", + binary, + config_path.to_string_lossy() + ); } "help" => { app.help();