melib/utils: add hostname() utility function
Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>pull/354/head
parent
70fc2b455c
commit
1048ce6824
|
@ -1262,7 +1262,7 @@ mod dotaddressable {
|
|||
|
||||
#[test]
|
||||
fn test_config_parse() {
|
||||
use std::{fmt::Write, fs, io::prelude::*, path::PathBuf};
|
||||
use std::{fmt::Write, fs, path::PathBuf};
|
||||
|
||||
struct ConfigFile {
|
||||
path: PathBuf,
|
||||
|
@ -1319,11 +1319,8 @@ send_mail = 'false'
|
|||
|
||||
impl ConfigFile {
|
||||
fn new(content: &str) -> std::result::Result<Self, std::io::Error> {
|
||||
let mut f = fs::File::open("/dev/urandom")?;
|
||||
let mut buf = [0u8; 16];
|
||||
f.read_exact(&mut buf)?;
|
||||
let mut filename = String::with_capacity(2 * 16);
|
||||
for byte in &buf {
|
||||
for byte in melib::utils::random::random_u64().to_be_bytes() {
|
||||
write!(&mut filename, "{:02X}", byte).unwrap();
|
||||
}
|
||||
let mut path = std::env::temp_dir();
|
||||
|
|
|
@ -37,7 +37,7 @@ libc = { version = "0.2.125", features = ["extra_traits"] }
|
|||
libloading = "^0.7"
|
||||
log = { version = "0.4", features = ["std"] }
|
||||
native-tls = { version = "0.2.3", default-features = false, optional = true }
|
||||
nix = { version = "0.27", default-features = false, features = ["fs", "socket", "dir"] }
|
||||
nix = { version = "0.27", default-features = false, features = ["fs", "socket", "dir", "hostname"] }
|
||||
nom = { version = "7" }
|
||||
notify = { version = "4.0.15", optional = true }
|
||||
polling = "2.8"
|
||||
|
|
|
@ -390,6 +390,13 @@ impl ErrorKind {
|
|||
is_variant! { is_value_error, ValueError }
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! src_err_arc_wrap {
|
||||
($err:expr) => {{
|
||||
(Box::new($err) as Box<dyn std::error::Error + Send + Sync + 'static>).into()
|
||||
}};
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Error {
|
||||
pub summary: Cow<'static, str>,
|
||||
|
|
|
@ -39,6 +39,7 @@ use crate::{
|
|||
|
||||
extern crate notify;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
collections::{hash_map::DefaultHasher, HashMap, HashSet},
|
||||
ffi::OsStr,
|
||||
fs,
|
||||
|
@ -1247,26 +1248,25 @@ impl MaildirType {
|
|||
}
|
||||
path.push("cur");
|
||||
{
|
||||
let mut rand_buf = [0u8; 16];
|
||||
let mut f =
|
||||
fs::File::open("/dev/urandom").expect("Could not open /dev/urandom for reading");
|
||||
f.read_exact(&mut rand_buf)
|
||||
.expect("Could not read from /dev/urandom/");
|
||||
let mut hostn_buf = String::with_capacity(256);
|
||||
let mut f =
|
||||
fs::File::open("/etc/hostname").expect("Could not open /etc/hostname for reading");
|
||||
f.read_to_string(&mut hostn_buf)
|
||||
.expect("Could not read from /etc/hostname");
|
||||
let timestamp = std::time::SystemTime::now()
|
||||
.duration_since(std::time::SystemTime::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis();
|
||||
type BeBytes128 = [u8; 16];
|
||||
debug_assert_eq!(std::mem::size_of::<u64>(), 8);
|
||||
debug_assert_eq!(
|
||||
std::mem::size_of::<BeBytes128>(),
|
||||
2 * std::mem::size_of::<[u8; 8]>()
|
||||
);
|
||||
let mut rand_num: BeBytes128 = [0u8; 16];
|
||||
rand_num[0..8].copy_from_slice(&crate::utils::random::random_u64().to_be_bytes());
|
||||
rand_num[8..].copy_from_slice(&crate::utils::random::random_u64().to_be_bytes());
|
||||
let hostname = crate::utils::hostname::hostname()
|
||||
.ok()
|
||||
.and_then(|osstr| osstr.into_string().ok().map(Cow::Owned))
|
||||
.unwrap_or(Cow::Borrowed("localhost"));
|
||||
let mut filename = format!(
|
||||
"{}.{:x}_{}.{}:2,",
|
||||
timestamp,
|
||||
u128::from_be_bytes(rand_buf),
|
||||
crate::utils::random::clock_millis(),
|
||||
u128::from_be_bytes(rand_num),
|
||||
std::process::id(),
|
||||
hostn_buf.trim()
|
||||
hostname.trim()
|
||||
);
|
||||
if let Some(flags) = flags {
|
||||
if !(flags & Flag::DRAFT).is_empty() {
|
||||
|
|
|
@ -207,3 +207,31 @@ impl std::ops::Not for SortOrder {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod hostname {
|
||||
//! Get local hostname.
|
||||
use crate::error::{Error, ErrorKind, IntoError, Result};
|
||||
use crate::src_err_arc_wrap;
|
||||
use std::io::Read;
|
||||
|
||||
/// Get local hostname with the `gethostname()` libc function.
|
||||
pub fn hostname() -> Result<std::ffi::OsString> {
|
||||
let retval = nix::unistd::gethostname().map_err(|err| {
|
||||
Error::new("Could not discover local hostname")
|
||||
.set_source(Some(src_err_arc_wrap! {err}))
|
||||
.set_err_kind(ErrorKind::OSError)
|
||||
});
|
||||
if retval.is_err() {
|
||||
let mut hostn_buf = String::with_capacity(256);
|
||||
if matches!(
|
||||
std::fs::File::open("/etc/hostname")
|
||||
.ok()
|
||||
.and_then(|mut f| f.read_to_string(&mut hostn_buf).ok()),
|
||||
Some(n) if n > 0
|
||||
) {
|
||||
return Ok(hostn_buf.into());
|
||||
}
|
||||
}
|
||||
retval
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,3 +69,10 @@ pub fn clock() -> u64 {
|
|||
.unwrap()
|
||||
.as_secs()
|
||||
}
|
||||
|
||||
pub fn clock_millis() -> u128 {
|
||||
SystemTime::now()
|
||||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue