melib/utils: add hostname() utility function

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
pull/354/head
Manos Pitsidianakis 2024-02-08 16:01:29 +02:00
parent 70fc2b455c
commit 1048ce6824
Signed by: Manos Pitsidianakis
GPG Key ID: 7729C7707F7E09D0
6 changed files with 62 additions and 23 deletions

View File

@ -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();

View File

@ -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"

View File

@ -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>,

View File

@ -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() {

View File

@ -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
}
}

View File

@ -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()
}