vpnchecker 0.1.0

VPN kill switch for macOS: outbound traffic leaves only through the VPN (pf), with a wildcard domain allowlist
use std::path::PathBuf;
use std::time::{SystemTime, UNIX_EPOCH};

use anyhow::{Context, Result, bail};
use nix::unistd::{Uid, User, geteuid, getuid};

pub fn is_root() -> bool {
    geteuid().is_root()
}

pub fn require_root() -> Result<()> {
    if !is_root() {
        bail!("this command requires root, run it with sudo");
    }
    Ok(())
}

/// The real user behind sudo, or the current user.
pub fn invoking_user() -> Result<User> {
    if is_root()
        && let Ok(name) = std::env::var("SUDO_USER")
        && let Some(user) = User::from_name(&name)?
    {
        return Ok(user);
    }
    User::from_uid(getuid())?.context("cannot determine current user")
}

pub fn default_config_path() -> Result<PathBuf> {
    Ok(invoking_user()?.dir.join(".config/vpnchecker/config.yaml"))
}

pub fn file_owner(path: &std::path::Path) -> Option<Uid> {
    use std::os::unix::fs::MetadataExt;
    std::fs::metadata(path).ok().map(|m| Uid::from_raw(m.uid()))
}

pub fn now_unix() -> u64 {
    SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .map(|d| d.as_secs())
        .unwrap_or(0)
}