install_package works :yay:!

onto the CLI
This commit is contained in:
Arthur Beck 2025-03-10 17:36:23 -05:00
parent aa66e60019
commit 454958e95d
Signed by: ArthurB
GPG key ID: ACE3D14F5CEF14BF
2 changed files with 52 additions and 18 deletions

View file

@ -989,6 +989,11 @@ pub fn receive_package(
let tar = ruzstd::decoding::StreamingDecoder::new(&mut reader).unwrap(); let tar = ruzstd::decoding::StreamingDecoder::new(&mut reader).unwrap();
let mut archive = tar::Archive::new(tar); let mut archive = tar::Archive::new(tar);
std::fs::remove_dir_all(&dir)?;
std::fs::create_dir(&dir)?;
archive.set_overwrite(true);
archive.set_preserve_ownerships(false);
archive.set_preserve_mtime(true);
archive.unpack(&dir)?; archive.unpack(&dir)?;
let mut packages = std::fs::OpenOptions::new() let mut packages = std::fs::OpenOptions::new()
@ -1081,32 +1086,56 @@ pub fn install_package(
#[derive(Clone)] #[derive(Clone)]
struct VisitDir<'a> { struct VisitDir<'a> {
/// Fuck me. /// Fuck me.
f: &'a dyn Fn(std::io::Result<std::fs::DirEntry>, VisitDir) -> std::io::Result<()> f: &'a dyn Fn(std::io::Result<std::fs::DirEntry>, VisitDir) -> std::io::Result<()>,
} }
let diritem = VisitDir { let diritem = VisitDir {
f: &|entry: std::io::Result<std::fs::DirEntry>, visit_dir: VisitDir| -> std::io::Result<()> { f: &|entry: std::io::Result<std::fs::DirEntry>,
visit_dir: VisitDir|
-> std::io::Result<()> {
let entry = entry?; let entry = entry?;
let entry_path = PathBuf::from(
entry
.path()
.to_string_lossy()
.strip_prefix(path.to_string_lossy().as_str())
.unwrap_or(&entry.path().to_string_lossy())
.strip_prefix("/")
.unwrap_or(&entry.path().to_string_lossy()),
);
println!("{}", entry_path.clone().to_string_lossy());
if entry.file_name() == *".BUILDINFO" if entry.file_name() == *".BUILDINFO"
|| entry.file_name() == *".MTREE" || entry.file_name() == *".MTREE"
|| entry.file_name() == *".PKGINFO" || entry.file_name() == *".PKGINFO"
{ {
return Ok(()); return Ok(());
} }
if entry.file_name() == *".INSTALL" {
std::fs::copy(path.join(&entry_path), out.join(&entry_path))?;
return Ok(());
}
if entry.file_type()?.is_dir() { if entry.file_type()?.is_dir() {
std::fs::create_dir_all(out.join(entry.path()))?; if !std::fs::exists(out.join(&entry_path))? {
for entry in std::fs::read_dir(path.join(entry.path()))? { std::fs::create_dir_all(out.join(&entry_path))?;
}
for entry in std::fs::read_dir(path.join(&entry_path))? {
(visit_dir.clone().f)(entry, visit_dir.clone())?; (visit_dir.clone().f)(entry, visit_dir.clone())?;
} }
} else { } else {
std::fs::create_dir_all(out.join(entry.path().parent().unwrap()))?; if !std::fs::exists(out.join(entry_path.parent().unwrap()))? {
std::fs::remove_file(out.join(entry.path()))?; std::fs::create_dir_all(out.join(entry_path.parent().unwrap()))?;
std::os::unix::fs::symlink(path.join(entry.path()), out.join(entry.path()))?; }
if std::fs::exists(out.join(&entry_path))? {
std::fs::remove_file(&entry_path)?;
}
std::os::unix::fs::symlink(path.join(&entry_path), out.join(&entry_path))?;
} }
Ok(()) Ok(())
} },
}; };
for entry in std::fs::read_dir(&path)? { for entry in std::fs::read_dir(&path)? {
@ -1114,11 +1143,17 @@ pub fn install_package(
} }
if std::fs::exists(out.join(".INSTALL"))? { if std::fs::exists(out.join(".INSTALL"))? {
if users::get_effective_uid() == 0 {
std::os::unix::fs::chroot(&out)?; std::os::unix::fs::chroot(&out)?;
} else {
println!("[WARN] .INSTALL script for package {} is being run without a chroot.", path.file_name().unwrap().to_string_lossy());
println!("[WARN] The script may give permission errors or ask for authentication.");
println!(" [TIP] To run in a chroot, run the program as root.");
}
if !std::process::Command::new("/usr/bin/bash") if !std::process::Command::new("/usr/bin/bash")
.arg("-c") .arg("-c")
.arg("source /.INSTALL && post_install && post_upgrade") .arg("source ./.INSTALL && post_install && post_upgrade")
.current_dir(&out) .current_dir(&out)
.spawn()? .spawn()?
.wait()? .wait()?
@ -1130,7 +1165,9 @@ pub fn install_package(
); );
} }
if users::get_effective_uid() == 0 {
std::os::unix::fs::chroot(".")?; std::os::unix::fs::chroot(".")?;
}
std::fs::remove_file(out.join(".INSTALL"))?; std::fs::remove_file(out.join(".INSTALL"))?;
} }
@ -1155,10 +1192,7 @@ pub fn install_package(
/// for the current user if not. If [std::fs::create_dir_all] returns an error, it will be /// for the current user if not. If [std::fs::create_dir_all] returns an error, it will be
/// propagated. /// propagated.
pub fn create_directories() -> Result<(), std::io::Error> { pub fn create_directories() -> Result<(), std::io::Error> {
if users::get_effective_uid() == 0 if users::get_effective_uid() == 0 || get_current_user() == "pacwoman" {
|| get_current_user() == "pacwoman"
|| get_current_user() == "arthur"
{
store_directory(true)?; store_directory(true)?;
config_directory(true)?; config_directory(true)?;
index_directory()?; index_directory()?;

View file

@ -22,7 +22,7 @@ fn main() -> std::io::Result<()> {
println!("found package"); println!("found package");
pacwoman::install_package(pacwoman::Mirror::new(url::Url::parse( pacwoman::install_package(pacwoman::Mirror::new(url::Url::parse(
"https://geo.mirror.pkgbuild.com/$repo/os/$arch", "https://geo.mirror.pkgbuild.com/$repo/os/$arch",
).unwrap()), package.1, package.0, true)?; ).unwrap()), package.1, package.0, false)?;
} }
Ok(()) Ok(())