Mercurial > crates > nonstick
comparison libpam-sys/src/structs.rs @ 109:bb465393621f
Minor cleanup and reorg.
- Use those nice new macros we just implemented.
- Straighten out the macro file.
- Move the `BinaryPayload` into `structs.rs`, leaving helpers behind.
| author | Paul Fisher <paul@pfish.zone> |
|---|---|
| date | Sat, 28 Jun 2025 02:49:35 -0400 |
| parents | libpam-sys/src/helpers.rs@49d9e2b5c189 |
| children | 20f7712a6857 |
comparison
equal
deleted
inserted
replaced
| 108:e97534be35e3 | 109:bb465393621f |
|---|---|
| 1 use core::marker::{PhantomData, PhantomPinned}; | |
| 2 use core::slice; | |
| 3 | |
| 4 /// The structure of the "binary message" payload for the `PAM_BINARY_PROMPT` | |
| 5 /// extension from Linux-PAM. | |
| 6 pub struct BinaryPayload { | |
| 7 /// The total byte size of the message, including this header, | |
| 8 /// as a u32 in network byte order (big endian). | |
| 9 pub total_bytes_u32be: [u8; 4], | |
| 10 /// A tag used to provide some kind of hint as to what the data is. | |
| 11 /// Its meaning is undefined. | |
| 12 pub data_type: u8, | |
| 13 /// Where the data itself would start, used as a marker to make this | |
| 14 /// not [`Unpin`] (since it is effectively an intrusive data structure | |
| 15 /// pointing to immediately after itself). | |
| 16 pub _marker: PhantomData<PhantomPinned>, | |
| 17 } | |
| 18 | |
| 19 impl BinaryPayload { | |
| 20 /// The most data it's possible to put into a [`BinaryPayload`]. | |
| 21 pub const MAX_SIZE: usize = (u32::MAX - 5) as usize; | |
| 22 | |
| 23 /// Fills in the provided buffer with the given data. | |
| 24 /// | |
| 25 /// This uses [`copy_from_slice`](slice::copy_from_slice) internally, | |
| 26 /// so `buf` must be exactly 5 bytes longer than `data`, or this function | |
| 27 /// will panic. | |
| 28 pub fn fill(buf: &mut [u8], data_type: u8, data: &[u8]) { | |
| 29 let ptr: *mut Self = buf.as_mut_ptr().cast(); | |
| 30 // SAFETY: We're given a slice, which always has a nonzero pointer. | |
| 31 let me = unsafe { ptr.as_mut().unwrap_unchecked() }; | |
| 32 me.total_bytes_u32be = u32::to_be_bytes(buf.len() as u32); | |
| 33 me.data_type = data_type; | |
| 34 buf[5..].copy_from_slice(data) | |
| 35 } | |
| 36 | |
| 37 /// The size of the message contained in the buffer. | |
| 38 fn len(&self) -> usize { | |
| 39 self.total_bytes().saturating_sub(5) | |
| 40 } | |
| 41 | |
| 42 /// The total storage needed for the message, including header. | |
| 43 pub fn total_bytes(&self) -> usize { | |
| 44 u32::from_be_bytes(self.total_bytes_u32be) as usize | |
| 45 } | |
| 46 | |
| 47 /// Gets the contents of the BinaryMessage stored at the given pointer. | |
| 48 /// | |
| 49 /// The returned data slice is borrowed from where the pointer points to. | |
| 50 /// | |
| 51 /// # Safety | |
| 52 /// | |
| 53 /// - The pointer must point to a valid `BinaryPayload`. | |
| 54 /// - The borrowed data must not outlive the validity of this pointer. | |
| 55 pub unsafe fn contents<'a>(ptr: *const Self) -> (u8, &'a [u8]) { | |
| 56 let header: &Self = ptr.as_ref().unwrap_unchecked(); | |
| 57 let typ = header.data_type; | |
| 58 ( | |
| 59 typ, | |
| 60 slice::from_raw_parts(ptr.cast::<u8>().offset(5), header.len()), | |
| 61 ) | |
| 62 } | |
| 63 } |
