1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
| | // SPDX-License-Identifier: EUPL-1.2+
// SPDX-FileCopyrightText: 2025 Alyssa Ross <hi@alyssa.is>
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<String, String> {
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);
}
|