diff --git a/proxmox-router/Cargo.toml b/proxmox-router/Cargo.toml index b1827bd7..60f346f7 100644 --- a/proxmox-router/Cargo.toml +++ b/proxmox-router/Cargo.toml @@ -12,6 +12,7 @@ exclude = [ "debian" ] anyhow = "1.0" http = "0.2" hyper = { version = "0.14", features = [ "full" ] } +nix = "0.19.1" percent-encoding = "2.1" serde_json = "1.0" unicode-width ="0.1.8" diff --git a/proxmox-router/src/cli/completion_helpers.rs b/proxmox-router/src/cli/completion_helpers.rs new file mode 100644 index 00000000..64709d3d --- /dev/null +++ b/proxmox-router/src/cli/completion_helpers.rs @@ -0,0 +1,57 @@ +use std::path::PathBuf; +use std::collections::HashMap; + +use nix::dir::Dir; +use nix::fcntl::{AtFlags, OFlag}; +use nix::sys::stat::{fstatat, Mode}; + +pub fn complete_file_name(arg: &str, _param: &HashMap) -> Vec { + let mut result = vec![]; + + let mut dirname = PathBuf::from(if arg.is_empty() { "./" } else { arg }); + + let is_dir = match fstatat(libc::AT_FDCWD, &dirname, AtFlags::empty()) { + Ok(stat) => (stat.st_mode & libc::S_IFMT) == libc::S_IFDIR, + Err(_) => false, + }; + + if !is_dir { + if let Some(parent) = dirname.parent() { + dirname = parent.to_owned(); + } + } + + let mut dir = + match Dir::openat(libc::AT_FDCWD, &dirname, OFlag::O_DIRECTORY, Mode::empty()) { + Ok(d) => d, + Err(_) => return result, + }; + + for item in dir.iter() { + if let Ok(entry) = item { + if let Ok(name) = entry.file_name().to_str() { + if name == "." || name == ".." { + continue; + } + let mut newpath = dirname.clone(); + newpath.push(name); + + if let Ok(stat) = fstatat(libc::AT_FDCWD, &newpath, AtFlags::empty()) + { + if (stat.st_mode & libc::S_IFMT) == libc::S_IFDIR { + newpath.push(""); + if let Some(newpath) = newpath.to_str() { + result.push(newpath.to_owned()); + } + continue; + } + } + if let Some(newpath) = newpath.to_str() { + result.push(newpath.to_owned()); + } + } + } + } + + result +} diff --git a/proxmox-router/src/cli/mod.rs b/proxmox-router/src/cli/mod.rs index 1494e319..cc724029 100644 --- a/proxmox-router/src/cli/mod.rs +++ b/proxmox-router/src/cli/mod.rs @@ -31,6 +31,9 @@ pub use text_table::*; mod completion; pub use completion::*; +mod completion_helpers; +pub use completion_helpers::*; + mod getopts; pub use getopts::*;