comparison libpam-sys/libpam-sys-impls/build.rs @ 116:a12706e42c9d

Logging, macros, and building: - Changes logging API to accept the `Location` of the log statement. Fixes OpenPAM implementation. - Stops publicly exporting doc macros. - Uses dlopen to detect the PAM library rather than header jankery.
author Paul Fisher <paul@pfish.zone>
date Sun, 29 Jun 2025 18:27:51 -0400
parents 178310336596
children 39760dfc9b3b
comparison
equal deleted inserted replaced
115:1e11a52b4665 116:a12706e42c9d
7 //! the macros in `libpam-sys-impl`. 7 //! the macros in `libpam-sys-impl`.
8 8
9 use proc_macro2::TokenStream; 9 use proc_macro2::TokenStream;
10 use quote::quote; 10 use quote::quote;
11 use std::{env, fs}; 11 use std::{env, fs};
12 use std::ffi::c_void;
12 use strum::EnumString; 13 use strum::EnumString;
14 use dlopen::raw::Library;
13 15
14 fn main() { 16 fn main() {
15 let pam_impl = match option_env!("LIBPAMSYS_IMPL") { 17 let pam_impl = match option_env!("LIBPAMSYS_IMPL") {
16 // The default option: Guess what PAM impl we're using based on OS. 18 // The default option: Guess what PAM impl we're using based on OS.
17 None => { 19 None => {
30 } else { 32 } else {
31 PamImpl::MinimalOpenPam 33 PamImpl::MinimalOpenPam
32 } 34 }
33 } 35 }
34 Some("_detect") => { 36 Some("_detect") => {
35 // Detect which impl it is from system headers. 37 // Detect what library we're using based on the symbols.
36 if header_exists("security/_pam_types.h") { 38 let lib = Library::open("libpam.so").unwrap();
39 if symbol_exists(&lib, "pam_syslog") {
37 PamImpl::LinuxPam 40 PamImpl::LinuxPam
38 } else if header_exists("security/openpam.h") { 41 } else if symbol_exists(&lib, "_openpam_log") {
39 PamImpl::OpenPam 42 PamImpl::OpenPam
40 } else if header_exists("security/pam_appl.h") { 43 } else if header_exists("security/pam_appl.h") {
41 // We figure we're *probably* on a Sun derivative. 44 // We figure we're *probably* on a Sun derivative.
42 PamImpl::Sun 45 PamImpl::Sun
43 } else { 46 } else {
54 format!("{}/pam_impl_enum.rs", env::var("OUT_DIR").unwrap()), 57 format!("{}/pam_impl_enum.rs", env::var("OUT_DIR").unwrap()),
55 PamImpl::enum_tokens().to_string(), 58 PamImpl::enum_tokens().to_string(),
56 ) 59 )
57 .unwrap(); 60 .unwrap();
58 println!("cargo:rustc-env=LIBPAMSYS_IMPL={pam_impl:?}"); 61 println!("cargo:rustc-env=LIBPAMSYS_IMPL={pam_impl:?}");
62 }
63
64 fn symbol_exists(lib: &Library, symbol: &str) -> bool {
65 unsafe { lib.symbol::<*mut c_void>(symbol) }.is_ok()
59 } 66 }
60 67
61 /// This defines a local enum with an `enum_tokens()` method that can spit out 68 /// This defines a local enum with an `enum_tokens()` method that can spit out
62 /// its own contents. 69 /// its own contents.
63 macro_rules! self_aware_enum { 70 macro_rules! self_aware_enum {