Files
RedBear-OS/src/config/file_impl.rs
T
2025-11-22 09:15:25 -08:00

73 lines
2.2 KiB
Rust

use anyhow::Result;
use libc::{gid_t, uid_t};
use std::ffi::{CString, OsStr};
use std::fs::{self, File};
use std::io::{Error, Write};
use std::os::unix::ffi::OsStrExt;
use std::os::unix::fs::{symlink, PermissionsExt};
use std::path::Path;
fn chown<P: AsRef<Path>>(path: P, uid: uid_t, gid: gid_t, recursive: bool) -> Result<()> {
let path = path.as_ref();
let c_path = CString::new(path.as_os_str().as_bytes()).unwrap();
if unsafe { libc::chown(c_path.as_ptr(), uid, gid) } != 0 {
return Err(Error::last_os_error().into());
}
if recursive && path.is_dir() {
for entry_res in fs::read_dir(path)? {
let entry = entry_res?;
chown(entry.path(), uid, gid, recursive)?;
}
}
Ok(())
}
// TODO: Rewrite impls
impl crate::FileConfig {
pub(crate) fn create<P: AsRef<Path>>(&self, prefix: P) -> Result<()> {
let path = self.path.trim_start_matches('/');
let target_file = prefix.as_ref().join(path);
if self.directory {
println!("Create directory {}", target_file.display());
fs::create_dir_all(&target_file)?;
self.apply_perms(&target_file)?;
return Ok(());
} else if let Some(parent) = target_file.parent() {
println!("Create file parent {}", parent.display());
fs::create_dir_all(parent)?;
}
if self.symlink {
println!("Create symlink {}", target_file.display());
symlink(&OsStr::new(&self.data), &target_file)?;
Ok(())
} else {
println!("Create file {}", target_file.display());
let mut file = File::create(&target_file)?;
file.write_all(self.data.as_bytes())?;
self.apply_perms(target_file)
}
}
fn apply_perms<P: AsRef<Path>>(&self, target: P) -> Result<()> {
let path = target.as_ref();
let mode = self
.mode
.unwrap_or_else(|| if self.directory { 0o0755 } else { 0o0644 });
let uid = self.uid.unwrap_or(!0);
let gid = self.gid.unwrap_or(!0);
// chmod
fs::set_permissions(path, fs::Permissions::from_mode(mode))?;
// chown
chown(path, uid, gid, self.recursive_chown)
}
}