use std::{os::{unix::prelude::PermissionsExt, linux::fs::MetadataExt}, fs, io::ErrorKind}; use nix::unistd; pub fn write_file(dir: &str, file: &str, data: &str) -> Result<(), Box> { std::fs::create_dir_all(dir)?; make_file_root(dir)?; let path = path(dir, file); std::fs::write(&path, "")?; make_file_root(&path)?; std::fs::write(&path, data)?; Ok(()) } pub fn read_file(dir: &str, file: &str) -> Option { let path = path(dir,file); if !is_file_root(&path) { return None; } match std::fs::read_to_string(&path) { Ok(data) => return Some(data), Err(_) => return None }; } fn make_file_root(path: &str) -> Result<(), Box> { unistd::chown(std::path::Path::new(path), Some(unistd::Uid::from(0)), Some(unistd::Gid::from(0)))?; let metadata = std::fs::metadata(path)?; let mut perms = metadata.permissions(); perms.set_mode(0o100600); fs::set_permissions(path, perms)?; Ok(()) } fn is_file_root(path: &str) -> bool { return check_file_permissions(0, 0, 0o100600, path); } fn check_file_permissions(uid: u32, gid: u32, mode: u32, path: &str) -> bool { let metadata = match std::fs::metadata(path) { Ok(data) => data, Err(e) => { return e.kind() == ErrorKind::NotFound } }; let perms = metadata.permissions(); return perms.mode() == mode && metadata.st_uid() == uid && metadata.st_gid() == gid; } fn path(dir: &str, file: &str) -> String { return format!("{}/{}", dir, file); }