leviso_elf/
paths.rs

1//! Library and binary path searching.
2
3use std::path::{Path, PathBuf};
4
5/// Find a library in standard paths within a rootfs.
6///
7/// Searches lib64, lib, and systemd private library paths.
8/// The `extra_paths` parameter allows callers to add additional search paths
9/// (e.g., `/usr/libexec/sudo` for rootfs builds).
10pub fn find_library(source_root: &Path, lib_name: &str, extra_paths: &[&str]) -> Option<PathBuf> {
11    // Standard library paths
12    let mut candidates = vec![
13        source_root.join("usr/lib64").join(lib_name),
14        source_root.join("lib64").join(lib_name),
15        source_root.join("usr/lib").join(lib_name),
16        source_root.join("lib").join(lib_name),
17        // Systemd private libraries
18        source_root.join("usr/lib64/systemd").join(lib_name),
19        source_root.join("usr/lib/systemd").join(lib_name),
20    ];
21
22    // Add extra paths from caller
23    for extra in extra_paths {
24        candidates.push(source_root.join(extra).join(lib_name));
25    }
26
27    candidates
28        .into_iter()
29        .find(|p| p.exists() || p.is_symlink())
30}
31
32/// Find a binary in standard bin/sbin directories.
33pub fn find_binary(source_root: &Path, binary: &str) -> Option<PathBuf> {
34    let bin_candidates = [
35        source_root.join("usr/bin").join(binary),
36        source_root.join("bin").join(binary),
37        source_root.join("usr/sbin").join(binary),
38        source_root.join("sbin").join(binary),
39    ];
40
41    bin_candidates.into_iter().find(|p| p.exists())
42}
43
44/// Find a binary, prioritizing sbin directories.
45pub fn find_sbin_binary(source_root: &Path, binary: &str) -> Option<PathBuf> {
46    let sbin_candidates = [
47        source_root.join("usr/sbin").join(binary),
48        source_root.join("sbin").join(binary),
49        source_root.join("usr/bin").join(binary),
50        source_root.join("bin").join(binary),
51    ];
52
53    sbin_candidates.into_iter().find(|p| p.exists())
54}