fix: handle = syntax and some tokens
This commit is contained in:
44
src/main.rs
44
src/main.rs
@@ -11,7 +11,7 @@
|
||||
//! [ssh(1)]: <https://manpages.debian.org/testing/manpages-de/ssh.1.de.html>
|
||||
//! [ssh_config(5)]: <https://manpages.debian.org/bullseye/openssh-client/ssh_config.5.en.html>
|
||||
|
||||
mod words;
|
||||
mod ssh;
|
||||
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
@@ -25,9 +25,7 @@ use std::{
|
||||
use clap::Parser;
|
||||
use glob::glob;
|
||||
|
||||
use crate::words::{Keyword, Words, expand};
|
||||
|
||||
const SYSTEM_CONFIG: &str = "/etc/ssh/ssh_config";
|
||||
use crate::ssh::{SSH_SYSTEM_CONFIG, SSH_USER_CONFIG, Words, expand_inlude_args, is_host_pattern};
|
||||
|
||||
/// List host names in ssh_config(5) files
|
||||
#[derive(Debug, Parser)]
|
||||
@@ -44,8 +42,8 @@ fn main() {
|
||||
Some(path) if path == "none" => vec![],
|
||||
Some(path) => vec![path.clone()],
|
||||
None => match env::home_dir() {
|
||||
Some(home) => vec![SYSTEM_CONFIG.into(), home.join(".ssh/config")],
|
||||
None => vec![SYSTEM_CONFIG.into()],
|
||||
Some(home) => vec![SSH_SYSTEM_CONFIG.into(), home.join(SSH_USER_CONFIG)],
|
||||
None => vec![SSH_SYSTEM_CONFIG.into()],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -61,7 +59,7 @@ fn main() {
|
||||
};
|
||||
}
|
||||
|
||||
let mut hosts = Vec::from_iter(hosts.into_iter());
|
||||
let mut hosts = Vec::from_iter(hosts);
|
||||
hosts.sort();
|
||||
hosts
|
||||
};
|
||||
@@ -94,30 +92,31 @@ fn find_hosts(filename: &Path) -> io::Result<HashSet<String>> {
|
||||
let line = buf[..n].trim();
|
||||
|
||||
let mut words: Words<'_> = line.into();
|
||||
let Some(Ok(directive)) = words.next() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let Ok(keyword) = Keyword::try_from(directive.as_str()) else {
|
||||
let Some(Ok(keyword)) = words.next() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
match keyword {
|
||||
Keyword::Include => find_hosts_in_include_directive(&mut hosts, words),
|
||||
Keyword::Host => find_hosts_in_host_directive(&mut hosts, words),
|
||||
k if k.eq_ignore_ascii_case("include") => {
|
||||
find_hosts_in_include_directive(&mut hosts, words);
|
||||
}
|
||||
k if k.eq_ignore_ascii_case("host") => {
|
||||
find_hosts_in_host_directive(&mut hosts, words);
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_hosts_in_include_directive(hosts: &mut HashSet<String>, words: Words<'_>) {
|
||||
for pattern in words {
|
||||
let Ok(pattern) = pattern else {
|
||||
for arg in words {
|
||||
let Ok(arg) = arg else {
|
||||
// TODO: print warning
|
||||
continue;
|
||||
};
|
||||
|
||||
// Expanding env vars before globbing is what ssh does as well.
|
||||
let Ok(pattern) = expand(&pattern) else {
|
||||
let Ok(pattern) = expand_inlude_args(arg) else {
|
||||
// TODO: print warning
|
||||
continue;
|
||||
};
|
||||
@@ -145,18 +144,17 @@ fn find_hosts_in_include_directive(hosts: &mut HashSet<String>, words: Words<'_>
|
||||
}
|
||||
|
||||
fn find_hosts_in_host_directive(hosts: &mut HashSet<String>, words: Words<'_>) {
|
||||
for host in words {
|
||||
let Ok(host) = host else {
|
||||
for word in words {
|
||||
let Ok(word) = word else {
|
||||
// TODO: print warning
|
||||
continue;
|
||||
};
|
||||
|
||||
if host.contains(['*', '?', '!', ',']) {
|
||||
// Ignore patterns (see ssh_config(5) "PATTERNS").
|
||||
if is_host_pattern(word) {
|
||||
continue;
|
||||
}
|
||||
|
||||
hosts.insert(host.into());
|
||||
hosts.insert(word.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +170,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
fn find_hosts() {
|
||||
let mut hosts = HashSet::new();
|
||||
find_hosts_in_host_directive(&mut hosts, "foo.test".into());
|
||||
assert!(hosts.contains("foo.test"));
|
||||
|
||||
Reference in New Issue
Block a user