aboutsummaryrefslogtreecommitdiffstats
path: root/src/config.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/config.rs58
1 files changed, 57 insertions, 1 deletions
diff --git a/src/config.rs b/src/config.rs
index 720c215..c05c3ae 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,6 +1,62 @@
1use std::env; 1use std::env;
2use std::io;
3use std::sync::OnceLock;
2 4
3pub const TEMP_PATH: &str = "/tmp/senator_sperma"; 5static TEMP_PATH: OnceLock<String> = OnceLock::new();
6
7/// Private per-process temp root. Initialized by [`init_temp_dir`] at startup.
8/// Falls back to the historical path only for code paths that run before init
9/// (tests).
10pub fn temp_path() -> &'static str {
11 TEMP_PATH
12 .get()
13 .map(String::as_str)
14 .unwrap_or("/tmp/senator_sperma")
15}
16
17/// Create/validate the temp directory with private permissions.
18///
19/// A fixed, predictable path in `/tmp` is a symlink target for any local user.
20/// Refuse a symlink (or non-directory) and force mode `0700` on the real
21/// directory before the bot writes anything into it.
22pub fn init_temp_dir() -> io::Result<()> {
23 let path = env::temp_dir().join("senator_sperma");
24 match std::fs::symlink_metadata(&path) {
25 Ok(meta) if meta.file_type().is_symlink() => {
26 return Err(io::Error::other(format!(
27 "{} is a symlink; refusing to use it",
28 path.display()
29 )));
30 }
31 Ok(meta) if !meta.is_dir() => {
32 return Err(io::Error::other(format!(
33 "{} exists and is not a directory",
34 path.display()
35 )));
36 }
37 Ok(_) => {}
38 Err(e) if e.kind() == io::ErrorKind::NotFound => {
39 let mut builder = std::fs::DirBuilder::new();
40 #[cfg(unix)]
41 {
42 use std::os::unix::fs::DirBuilderExt;
43 builder.mode(0o700);
44 }
45 builder.create(&path)?;
46 }
47 Err(e) => return Err(e),
48 }
49 #[cfg(unix)]
50 {
51 use std::os::unix::fs::PermissionsExt;
52 std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o700))?;
53 }
54 let encoded = path.to_string_lossy().into_owned();
55 TEMP_PATH
56 .set(encoded)
57 .map_err(|_| io::Error::other("temp directory already initialized"))?;
58 Ok(())
59}
4 60
5#[derive(Debug, Clone)] 61#[derive(Debug, Clone)]
6pub struct Config { 62pub struct Config {