// SPDX-License-Identifier: EUPL-1.2+ // SPDX-FileCopyrightText: 2025 Alyssa Ross mod keyfile; use std::env::args_os; use std::ffi::OsString; use std::fs::File; use std::io::{read_to_string, stderr, Write}; use std::os::fd::OwnedFd; use std::os::unix::prelude::*; use std::process::exit; use keyfile::parse; fn extract_runtime(mut metadata: File) -> Result { let metadata = read_to_string(&mut metadata).map_err(|e| e.to_string())?; let group = parse(&metadata).map_err(|e| e.to_string())?; let application = group .get("Application") .ok_or_else(|| "Application group missing".to_string())?; Ok(application .get("runtime") .ok_or_else(|| "runtime property missing".to_string())? .clone()) } // SAFETY: we do not expect "extract_runtime" to collide with another symbol. #[unsafe(export_name = "extract_runtime")] pub extern "C" fn extract_runtime_c(metadata: OwnedFd, out: &mut [u8; 256]) { let error = match extract_runtime(metadata.into()) { Err(e) => e, Ok(runtime) if runtime.len() >= out.len() => "runtime name too long".to_string(), Ok(runtime) => { out[..runtime.len()].copy_from_slice(runtime.as_bytes()); out[runtime.len()] = 0; return; } }; let prog_name = args_os() .next() .unwrap_or_else(|| OsString::from("mount-flatpak")); stderr().write_all(prog_name.as_bytes()).unwrap(); eprintln!(": {error}"); exit(1); }