lvp 1.0.0

Misc utilities for axum (dynamic TLS, OIDC, logger, errors, CORS, and JWT auth)
use std::{ffi::CString, os::unix::prelude::OsStrExt, path::Path};

use libc::statvfs64;

pub struct Stats {
    pub block_size: u64,
    pub fragment_size: u64,
    pub block_count: u64,
    pub blocks_free: u64,
    pub blocks_free_unprivileged: u64,
    pub inodes: u64,
    pub inodes_free: u64,
    pub inodes_free_unprivileged: u64,
    pub file_system_id: u64,
    pub flags: u64,
    pub filename_max_len: u64,
}

pub async fn statfs(path: &Path) -> std::io::Result<Stats> {
    let path: Vec<u8> = path.as_os_str().as_bytes().to_vec();
    tokio::task::spawn_blocking(move || {
        let path = CString::new(path).unwrap();
        let mut out: statvfs64 =
            unsafe { std::mem::transmute([0u8; std::mem::size_of::<statvfs64>()]) };
        let status = unsafe { libc::statvfs64(path.as_ptr(), (&mut out) as *mut statvfs64) };
        if status < 0 {
            return Err(std::io::Error::last_os_error());
        }
        Ok(Stats {
            block_size: out.f_bsize,
            fragment_size: out.f_frsize,
            block_count: out.f_blocks,
            blocks_free: out.f_bfree,
            blocks_free_unprivileged: out.f_bavail,
            inodes: out.f_files,
            inodes_free: out.f_ffree,
            inodes_free_unprivileged: out.f_favail,
            file_system_id: out.f_fsid,
            flags: out.f_flag,
            filename_max_len: out.f_flag,
        })
    })
    .await
    .unwrap()
}