mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 12:07:46 +00:00
Merge pull request #2684 from blyxxyz/hostname-cleanup
hostname: Cleanup
This commit is contained in:
commit
3d867fcf7c
2 changed files with 73 additions and 65 deletions
|
@ -68,6 +68,7 @@ structs
|
||||||
substr
|
substr
|
||||||
splitn
|
splitn
|
||||||
trunc
|
trunc
|
||||||
|
uninit
|
||||||
|
|
||||||
# * uutils
|
# * uutils
|
||||||
basenc
|
basenc
|
||||||
|
@ -277,6 +278,7 @@ ULONG
|
||||||
ULONGLONG
|
ULONGLONG
|
||||||
UNLEN
|
UNLEN
|
||||||
WCHAR
|
WCHAR
|
||||||
|
WSADATA
|
||||||
errhandlingapi
|
errhandlingapi
|
||||||
fileapi
|
fileapi
|
||||||
handleapi
|
handleapi
|
||||||
|
|
|
@ -10,18 +10,13 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use clap::{crate_version, App, Arg, ArgMatches};
|
|
||||||
use std::collections::hash_set::HashSet;
|
use std::collections::hash_set::HashSet;
|
||||||
use std::net::ToSocketAddrs;
|
use std::net::ToSocketAddrs;
|
||||||
use std::str;
|
use std::str;
|
||||||
#[cfg(windows)]
|
|
||||||
use uucore::error::UUsageError;
|
|
||||||
use uucore::error::{UResult, USimpleError};
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
use clap::{crate_version, App, Arg, ArgMatches};
|
||||||
use winapi::shared::minwindef::MAKEWORD;
|
|
||||||
#[cfg(windows)]
|
use uucore::error::{FromIo, UResult};
|
||||||
use winapi::um::winsock2::{WSACleanup, WSAStartup};
|
|
||||||
|
|
||||||
static ABOUT: &str = "Display or set the system's host name.";
|
static ABOUT: &str = "Display or set the system's host name.";
|
||||||
|
|
||||||
|
@ -31,45 +26,52 @@ static OPT_FQDN: &str = "fqdn";
|
||||||
static OPT_SHORT: &str = "short";
|
static OPT_SHORT: &str = "short";
|
||||||
static OPT_HOST: &str = "host";
|
static OPT_HOST: &str = "host";
|
||||||
|
|
||||||
#[uucore_procs::gen_uumain]
|
#[cfg(windows)]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
mod wsa {
|
||||||
#![allow(clippy::let_and_return)]
|
use std::io;
|
||||||
#[cfg(windows)]
|
|
||||||
unsafe {
|
use winapi::shared::minwindef::MAKEWORD;
|
||||||
#[allow(deprecated)]
|
use winapi::um::winsock2::{WSACleanup, WSAStartup, WSADATA};
|
||||||
let mut data = std::mem::uninitialized();
|
|
||||||
if WSAStartup(MAKEWORD(2, 2), &mut data as *mut _) != 0 {
|
pub(super) struct WsaHandle(());
|
||||||
return Err(UUsageError::new(
|
|
||||||
1,
|
pub(super) fn start() -> io::Result<WsaHandle> {
|
||||||
"Failed to start Winsock 2.2".to_string(),
|
let err = unsafe {
|
||||||
));
|
let mut data = std::mem::MaybeUninit::<WSADATA>::uninit();
|
||||||
|
WSAStartup(MAKEWORD(2, 2), data.as_mut_ptr())
|
||||||
|
};
|
||||||
|
if err != 0 {
|
||||||
|
Err(io::Error::from_raw_os_error(err))
|
||||||
|
} else {
|
||||||
|
Ok(WsaHandle(()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let result = execute(args);
|
|
||||||
#[cfg(windows)]
|
impl Drop for WsaHandle {
|
||||||
unsafe {
|
fn drop(&mut self) {
|
||||||
WSACleanup();
|
unsafe {
|
||||||
|
// This possibly returns an error but we can't handle it
|
||||||
|
let _err = WSACleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage() -> String {
|
fn usage() -> String {
|
||||||
format!("{0} [OPTION]... [HOSTNAME]", uucore::execution_phrase())
|
format!("{0} [OPTION]... [HOSTNAME]", uucore::execution_phrase())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute(args: impl uucore::Args) -> UResult<()> {
|
#[uucore_procs::gen_uumain]
|
||||||
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let usage = usage();
|
let usage = usage();
|
||||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||||
|
|
||||||
match matches.value_of(OPT_HOST) {
|
#[cfg(windows)]
|
||||||
|
let _handle = wsa::start().map_err_context(|| "failed to start Winsock".to_owned())?;
|
||||||
|
|
||||||
|
match matches.value_of_os(OPT_HOST) {
|
||||||
None => display_hostname(&matches),
|
None => display_hostname(&matches),
|
||||||
Some(host) => {
|
Some(host) => hostname::set(host).map_err_context(|| "failed to set hostname".to_owned()),
|
||||||
if let Err(err) = hostname::set(host) {
|
|
||||||
return Err(USimpleError::new(1, format!("{}", err)));
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,64 +83,68 @@ pub fn uu_app() -> App<'static, 'static> {
|
||||||
Arg::with_name(OPT_DOMAIN)
|
Arg::with_name(OPT_DOMAIN)
|
||||||
.short("d")
|
.short("d")
|
||||||
.long("domain")
|
.long("domain")
|
||||||
|
.overrides_with_all(&[OPT_DOMAIN, OPT_IP_ADDRESS, OPT_FQDN, OPT_SHORT])
|
||||||
.help("Display the name of the DNS domain if possible"),
|
.help("Display the name of the DNS domain if possible"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(OPT_IP_ADDRESS)
|
Arg::with_name(OPT_IP_ADDRESS)
|
||||||
.short("i")
|
.short("i")
|
||||||
.long("ip-address")
|
.long("ip-address")
|
||||||
|
.overrides_with_all(&[OPT_DOMAIN, OPT_IP_ADDRESS, OPT_FQDN, OPT_SHORT])
|
||||||
.help("Display the network address(es) of the host"),
|
.help("Display the network address(es) of the host"),
|
||||||
)
|
)
|
||||||
// TODO: support --long
|
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(OPT_FQDN)
|
Arg::with_name(OPT_FQDN)
|
||||||
.short("f")
|
.short("f")
|
||||||
.long("fqdn")
|
.long("fqdn")
|
||||||
|
.overrides_with_all(&[OPT_DOMAIN, OPT_IP_ADDRESS, OPT_FQDN, OPT_SHORT])
|
||||||
.help("Display the FQDN (Fully Qualified Domain Name) (default)"),
|
.help("Display the FQDN (Fully Qualified Domain Name) (default)"),
|
||||||
)
|
)
|
||||||
.arg(Arg::with_name(OPT_SHORT).short("s").long("short").help(
|
.arg(
|
||||||
"Display the short hostname (the portion before the first dot) if \
|
Arg::with_name(OPT_SHORT)
|
||||||
possible",
|
.short("s")
|
||||||
))
|
.long("short")
|
||||||
|
.overrides_with_all(&[OPT_DOMAIN, OPT_IP_ADDRESS, OPT_FQDN, OPT_SHORT])
|
||||||
|
.help("Display the short hostname (the portion before the first dot) if possible"),
|
||||||
|
)
|
||||||
.arg(Arg::with_name(OPT_HOST))
|
.arg(Arg::with_name(OPT_HOST))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn display_hostname(matches: &ArgMatches) -> UResult<()> {
|
fn display_hostname(matches: &ArgMatches) -> UResult<()> {
|
||||||
let hostname = hostname::get().unwrap().into_string().unwrap();
|
let hostname = hostname::get()
|
||||||
|
.map_err_context(|| "failed to get hostname".to_owned())?
|
||||||
|
.to_string_lossy()
|
||||||
|
.into_owned();
|
||||||
|
|
||||||
if matches.is_present(OPT_IP_ADDRESS) {
|
if matches.is_present(OPT_IP_ADDRESS) {
|
||||||
// XXX: to_socket_addrs needs hostname:port so append a dummy port and remove it later.
|
// XXX: to_socket_addrs needs hostname:port so append a dummy port and remove it later.
|
||||||
// This was originally supposed to use std::net::lookup_host, but that seems to be
|
// This was originally supposed to use std::net::lookup_host, but that seems to be
|
||||||
// deprecated. Perhaps we should use the dns-lookup crate?
|
// deprecated. Perhaps we should use the dns-lookup crate?
|
||||||
let hostname = hostname + ":1";
|
let hostname = hostname + ":1";
|
||||||
match hostname.to_socket_addrs() {
|
let addresses = hostname
|
||||||
Ok(addresses) => {
|
.to_socket_addrs()
|
||||||
let mut hashset = HashSet::new();
|
.map_err_context(|| "failed to resolve socket addresses".to_owned())?;
|
||||||
let mut output = String::new();
|
let mut hashset = HashSet::new();
|
||||||
for addr in addresses {
|
let mut output = String::new();
|
||||||
// XXX: not sure why this is necessary...
|
for addr in addresses {
|
||||||
if !hashset.contains(&addr) {
|
// XXX: not sure why this is necessary...
|
||||||
let mut ip = format!("{}", addr);
|
if !hashset.contains(&addr) {
|
||||||
if ip.ends_with(":1") {
|
let mut ip = addr.to_string();
|
||||||
let len = ip.len();
|
if ip.ends_with(":1") {
|
||||||
ip.truncate(len - 2);
|
let len = ip.len();
|
||||||
}
|
ip.truncate(len - 2);
|
||||||
output.push_str(&ip);
|
|
||||||
output.push(' ');
|
|
||||||
hashset.insert(addr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let len = output.len();
|
output.push_str(&ip);
|
||||||
if len > 0 {
|
output.push(' ');
|
||||||
println!("{}", &output[0..len - 1]);
|
hashset.insert(addr);
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Err(f) => {
|
|
||||||
return Err(USimpleError::new(1, format!("{}", f)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let len = output.len();
|
||||||
|
if len > 0 {
|
||||||
|
println!("{}", &output[0..len - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
if matches.is_present(OPT_SHORT) || matches.is_present(OPT_DOMAIN) {
|
if matches.is_present(OPT_SHORT) || matches.is_present(OPT_DOMAIN) {
|
||||||
let mut it = hostname.char_indices().filter(|&ci| ci.1 == '.');
|
let mut it = hostname.char_indices().filter(|&ci| ci.1 == '.');
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue