Merge pull request #2210 from jhscheer/dns_lookup

who: fix `--lookup`
This commit is contained in:
Sylvestre Ledru 2021-05-15 21:18:12 +02:00 committed by GitHub
commit 620a5a5df6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 78 additions and 61 deletions

24
Cargo.lock generated
View file

@ -576,6 +576,18 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "dns-lookup"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "093d88961fd18c4ecacb8c80cd0b356463ba941ba11e0e01f9cf5271380b79dc"
dependencies = [
"cfg-if 1.0.0",
"libc",
"socket2",
"winapi 0.3.9",
]
[[package]] [[package]]
name = "dunce" name = "dunce"
version = "1.0.1" version = "1.0.1"
@ -1445,6 +1457,17 @@ dependencies = [
"maybe-uninit", "maybe-uninit",
] ]
[[package]]
name = "socket2"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
dependencies = [
"cfg-if 1.0.0",
"libc",
"winapi 0.3.9",
]
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.8.0" version = "0.8.0"
@ -2668,6 +2691,7 @@ name = "uucore"
version = "0.0.8" version = "0.0.8"
dependencies = [ dependencies = [
"data-encoding", "data-encoding",
"dns-lookup",
"dunce", "dunce",
"getopts", "getopts",
"lazy_static", "lazy_static",

View file

@ -286,17 +286,10 @@ impl Pinky {
print!(" {}", time_string(&ut)); print!(" {}", time_string(&ut));
if self.include_where && !ut.host().is_empty() { let mut s = ut.host();
let ut_host = ut.host(); if self.include_where && !s.is_empty() {
let mut res = ut_host.splitn(2, ':'); s = safe_unwrap!(ut.canon_host());
let host = match res.next() { print!(" {}", s);
Some(_) => ut.canon_host().unwrap_or_else(|_| ut_host.clone()),
None => ut_host.clone(),
};
match res.next() {
Some(d) => print!(" {}:{}", host, d),
None => print!(" {}", host),
}
} }
println!(); println!();

View file

@ -548,20 +548,10 @@ impl Who {
" ?".into() " ?".into()
}; };
let mut buf = vec![]; let mut s = ut.host();
let ut_host = ut.host(); if self.do_lookup {
let mut res = ut_host.splitn(2, ':'); s = safe_unwrap!(ut.canon_host());
if let Some(h) = res.next() {
if self.do_lookup {
buf.push(ut.canon_host().unwrap_or_else(|_| h.to_owned()));
} else {
buf.push(h.to_owned());
}
} }
if let Some(h) = res.next() {
buf.push(h.to_owned());
}
let s = buf.join(":");
let hoststr = if s.is_empty() { s } else { format!("({})", s) }; let hoststr = if s.is_empty() { s } else { format!("({})", s) };
self.print_line( self.print_line(

View file

@ -16,6 +16,7 @@ edition = "2018"
path="src/lib/lib.rs" path="src/lib/lib.rs"
[dependencies] [dependencies]
dns-lookup = "1.0.5"
dunce = "1.0.0" dunce = "1.0.0"
getopts = "<= 0.2.21" getopts = "<= 0.2.21"
wild = "2.0.4" wild = "2.0.4"

View file

@ -188,47 +188,40 @@ impl Utmpx {
/// Canonicalize host name using DNS /// Canonicalize host name using DNS
pub fn canon_host(&self) -> IOResult<String> { pub fn canon_host(&self) -> IOResult<String> {
const AI_CANONNAME: libc::c_int = 0x2;
let host = self.host(); let host = self.host();
let host = host.split(':').next().unwrap();
let hints = libc::addrinfo { // TODO: change to use `split_once` when MSRV hits 1.52.0
ai_flags: AI_CANONNAME, // let (hostname, display) = host.split_once(':').unwrap_or((&host, ""));
ai_family: 0, let mut h = host.split(':');
ai_socktype: 0, let hostname = h.next().unwrap_or(&host);
ai_protocol: 0, let display = h.next().unwrap_or("");
ai_addrlen: 0,
ai_addr: ptr::null_mut(), if !hostname.is_empty() {
ai_canonname: ptr::null_mut(), extern crate dns_lookup;
ai_next: ptr::null_mut(), use dns_lookup::{getaddrinfo, AddrInfoHints};
};
let c_host = CString::new(host).unwrap(); const AI_CANONNAME: i32 = 0x2;
let mut res = ptr::null_mut(); let hints = AddrInfoHints {
let status = unsafe { flags: AI_CANONNAME,
libc::getaddrinfo( ..AddrInfoHints::default()
c_host.as_ptr(),
ptr::null(),
&hints as *const _,
&mut res as *mut _,
)
};
if status == 0 {
let info: libc::addrinfo = unsafe { ptr::read(res as *const _) };
// http://lists.gnu.org/archive/html/bug-coreutils/2006-09/msg00300.html
// says Darwin 7.9.0 getaddrinfo returns 0 but sets
// res->ai_canonname to NULL.
let ret = if info.ai_canonname.is_null() {
Ok(String::from(host))
} else {
Ok(unsafe { CString::from_raw(info.ai_canonname).into_string().unwrap() })
}; };
unsafe { let sockets = getaddrinfo(Some(&hostname), None, Some(hints))
libc::freeaddrinfo(res); .unwrap()
.collect::<IOResult<Vec<_>>>()?;
for socket in sockets {
if let Some(ai_canonname) = socket.canonname {
return Ok(if display.is_empty() {
ai_canonname
} else {
format!("{}:{}", ai_canonname, display)
});
}
} }
ret
} else {
Err(IOError::last_os_error())
} }
Ok(host.to_string())
} }
pub fn iter_all_records() -> UtmpxIter { pub fn iter_all_records() -> UtmpxIter {
UtmpxIter UtmpxIter
} }

View file

@ -98,6 +98,23 @@ fn test_short_format_q() {
assert_eq!(v_actual, v_expect); assert_eq!(v_actual, v_expect);
} }
#[cfg(target_os = "linux")]
#[test]
fn test_no_flag() {
let scene = TestScenario::new(util_name!());
let actual = scene.ucmd().succeeds().stdout_move_str();
let expect = scene
.cmd_keepenv(util_name!())
.env("LANGUAGE", "C")
.succeeds()
.stdout_move_str();
let v_actual: Vec<&str> = actual.split_whitespace().collect();
let v_expect: Vec<&str> = expect.split_whitespace().collect();
assert_eq!(v_actual, v_expect);
}
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
fn expected_result(args: &[&str]) -> String { fn expected_result(args: &[&str]) -> String {
TestScenario::new(util_name!()) TestScenario::new(util_name!())

View file

@ -162,7 +162,6 @@ fn test_users() {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[test] #[test]
#[ignore]
fn test_lookup() { fn test_lookup() {
for opt in vec!["--lookup"] { for opt in vec!["--lookup"] {
new_ucmd!() new_ucmd!()