diff --git a/Cargo.lock b/Cargo.lock index 8dc5c9b..d081954 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -382,6 +382,7 @@ dependencies = [ "tokio", "tokio-stream", "uuid", + "xdg", ] [[package]] @@ -807,3 +808,9 @@ name = "windows_x86_64_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "xdg" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" diff --git a/crates/muvm/Cargo.toml b/crates/muvm/Cargo.toml index 17f1ecc..4451d51 100644 --- a/crates/muvm/Cargo.toml +++ b/crates/muvm/Cargo.toml @@ -23,6 +23,7 @@ tempfile = { version = "3.10.1", default-features = false, features = [] } tokio = { version = "1.38.0", default-features = false, features = ["io-util", "macros", "net", "process", "rt-multi-thread", "sync"] } tokio-stream = { version = "0.1.15", default-features = false, features = ["net", "sync"] } uuid = { version = "1.10.0", default-features = false, features = ["std", "v7"] } +xdg = "2.5.2" [features] default = [] diff --git a/crates/muvm/src/guest/bin/muvm-guest.rs b/crates/muvm/src/guest/bin/muvm-guest.rs index 311b2ca..4a8d5d0 100644 --- a/crates/muvm/src/guest/bin/muvm-guest.rs +++ b/crates/muvm/src/guest/bin/muvm-guest.rs @@ -1,4 +1,5 @@ use std::cmp; +use std::env; use std::os::unix::process::CommandExt as _; use std::process::Command; @@ -13,6 +14,7 @@ use muvm::guest::sommelier::exec_sommelier; use muvm::guest::user::setup_user; use muvm::guest::x11::setup_x11_forwarding; use muvm::utils::env::find_in_path; +use nix::unistd::User; use rustix::process::{getrlimit, setrlimit, Resource}; fn main() -> Result<()> { @@ -40,6 +42,18 @@ fn main() -> Result<()> { } Command::new("/usr/lib/systemd/systemd-udevd").spawn()?; + let user = User::from_uid(options.uid)?.unwrap(); + + // Hack to fetch the XDG directories for our target user, before we + // change uid. + // SAFETY: Safe if and only if `muvm-guest` program is not multithreaded. + // See https://doc.rust-lang.org/std/env/fn.set_var.html#safety + env::set_var("HOME", user.dir); + let xdg_dirs = xdg::BaseDirectories::with_prefix("muvm")?; + // SAFETY: Safe if and only if `muvm-guest` program is not multithreaded. + // See https://doc.rust-lang.org/std/env/fn.set_var.html#safety + env::remove_var("HOME"); + setup_fex()?; configure_network()?; @@ -50,6 +64,14 @@ fn main() -> Result<()> { .spawn()?; } + for init_file in xdg_dirs.find_data_files("init.sh") { + Command::new(init_file) + .arg(format!("{}", options.uid)) + .arg(format!("{}", options.gid)) + .status() + .context("Failed to execute init.sh")?; + } + let run_path = match setup_user(options.username, options.uid, options.gid) { Ok(p) => p, Err(err) => return Err(err).context("Failed to set up user, bailing out"), @@ -63,6 +85,13 @@ fn main() -> Result<()> { setup_x11_forwarding(run_path)?; + for init_file in xdg_dirs.find_data_files("user.sh") { + eprintln!("{:?}", init_file); + Command::new(init_file) + .status() + .context("Failed to execute user.sh")?; + } + // Will not return if successful. exec_sommelier(&options.command, &options.command_args) .context("Failed to execute sommelier")?;