Mercurial > crates > nonstick
comparison libpam-sys/libpam-sys-helpers/build.rs @ 148:4b3a5095f68c
Move libpam-sys helpers into their own library.
- Renames libpam-sys-helpers to libpam-sys-consts.
- Moves libpam-sys-helpers::helpers into libpam-sys-helpers,
which moves them completely out of libpam-sys's dependency chain.
- Moves the aliases from libpam-sys into libpam-sys::aliases.
| author | Paul Fisher <paul@pfish.zone> |
|---|---|
| date | Mon, 07 Jul 2025 12:11:43 -0400 |
| parents | efbc235f01d3 |
| children | 0730f5f2ee2a |
comparison
equal
deleted
inserted
replaced
| 147:4d7333337569 | 148:4b3a5095f68c |
|---|---|
| 1 #![allow(unexpected_cfgs)] | 1 use libpam_sys_consts::pam_impl; |
| 2 | |
| 3 use std::ffi::{c_void, CString}; | |
| 4 use std::ptr::NonNull; | |
| 5 use std::{env, fs}; | |
| 6 | |
| 7 include!("src/pam_impl.rs"); | |
| 8 | 2 |
| 9 fn main() { | 3 fn main() { |
| 10 let pam_impl = match option_env!("LIBPAMSYS_IMPL") { | 4 println!("cargo:rustc-link-lib=pam"); |
| 11 // The default option: Guess what PAM impl we're using based on OS. | 5 pam_impl::enable_pam_impl_cfg(); |
| 12 None | Some("") => LibPam::detect(), | |
| 13 Some(other) => match PamImpl::try_from(other) { | |
| 14 Ok(i) => i, | |
| 15 Err(_) => { | |
| 16 panic!( | |
| 17 "unknown PAM implementation {other:?}. valid LIBPAMSYS_IMPLs are {:?}, or unset to detect", PamImpl::items() | |
| 18 ) | |
| 19 } | |
| 20 }, | |
| 21 }; | |
| 22 let impl_str = format!("{pam_impl:?}"); | |
| 23 println!("{}", generate_cfg(&impl_str)); | |
| 24 // We set this environment variable to substitute into docstrings. | |
| 25 println!("cargo:rustc-env=LIBPAMSYS_IMPL={impl_str}"); | |
| 26 fs::write( | |
| 27 format!("{}/pam_impl_const.rs", env::var("OUT_DIR").unwrap()), | |
| 28 generate_consts(&impl_str), | |
| 29 ) | |
| 30 .unwrap(); | |
| 31 } | 6 } |
| 32 | |
| 33 fn generate_consts(impl_str: &str) -> String { | |
| 34 format!( | |
| 35 "\ | |
| 36 impl PamImpl {{ | |
| 37 /// The implementation of libpam this was built for (`{impl_str}`). | |
| 38 pub const CURRENT: Self = Self::{impl_str}; | |
| 39 }} | |
| 40 | |
| 41 /// String name of [`PamImpl::CURRENT`], for substituting into docs. | |
| 42 #[macro_export] | |
| 43 macro_rules! pam_impl_name {{ () => ({impl_str:?}) }} | |
| 44 " | |
| 45 ) | |
| 46 } | |
| 47 | |
| 48 struct LibPam(NonNull<c_void>); | |
| 49 | |
| 50 impl LibPam { | |
| 51 fn detect() -> PamImpl { | |
| 52 if let Some(lib) = Self::open() { | |
| 53 if lib.has("pam_syslog") { | |
| 54 return PamImpl::LinuxPam; | |
| 55 } else if lib.has("_openpam_log") { | |
| 56 return PamImpl::OpenPam; | |
| 57 } else if lib.has("__pam_get_authtok") { | |
| 58 return PamImpl::Sun; | |
| 59 } | |
| 60 } | |
| 61 if cfg!(target_os = "linux") { | |
| 62 PamImpl::LinuxPam | |
| 63 } else if cfg!(any( | |
| 64 target_os = "macos", | |
| 65 target_os = "freebsd", | |
| 66 target_os = "netbsd", | |
| 67 target_os = "dragonfly", | |
| 68 target_os = "openbsd", | |
| 69 )) { | |
| 70 PamImpl::OpenPam | |
| 71 } else if cfg!(any(target_os = "illumos", target_os = "solaris")) { | |
| 72 PamImpl::Sun | |
| 73 } else { | |
| 74 PamImpl::XSso | |
| 75 } | |
| 76 } | |
| 77 | |
| 78 fn open() -> Option<Self> { | |
| 79 NonNull::new(unsafe { libc::dlopen(b"libpam.so\0".as_ptr().cast(), libc::RTLD_LAZY) }) | |
| 80 .map(Self) | |
| 81 } | |
| 82 | |
| 83 fn has(&self, name: &str) -> bool { | |
| 84 let name = CString::new(name).unwrap(); | |
| 85 let symbol = unsafe { libc::dlsym(self.0.as_ptr(), name.as_ptr()) }; | |
| 86 !symbol.is_null() | |
| 87 } | |
| 88 } | |
| 89 | |
| 90 impl Drop for LibPam { | |
| 91 fn drop(&mut self) { | |
| 92 unsafe { | |
| 93 libc::dlclose(self.0.as_ptr()); | |
| 94 } | |
| 95 } | |
| 96 } |
