101 lines
2.5 KiB
Rust
101 lines
2.5 KiB
Rust
use std::{error, ffi::{self, CStr}, fmt, io, num::TryFromIntError, str};
|
|
|
|
#[derive(Debug)]
|
|
pub enum Error {
|
|
Io(io::Error),
|
|
IncorrectPassword,
|
|
InvalidPassword,
|
|
IntCast,
|
|
PermissionDenied,
|
|
Nul(ffi::NulError),
|
|
Utf8(str::Utf8Error),
|
|
Other(String),
|
|
}
|
|
|
|
impl fmt::Display for Error {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match self {
|
|
Self::Io(e) => write!(f, "{e}"),
|
|
Self::IncorrectPassword => write!(f, "incorrect password"),
|
|
Self::InvalidPassword => write!(f, "invalid password"),
|
|
Self::IntCast => write!(f, "integer cast error"),
|
|
Self::PermissionDenied => write!(f, "permission denied"),
|
|
Self::Nul(e) => write!(f, "{e}"),
|
|
Self::Utf8(e) => write!(f, "{e}"),
|
|
Self::Other(e) => write!(f, "{e}"),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl error::Error for Error {
|
|
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
|
match self {
|
|
Self::Io(e) => Some(e),
|
|
Self::Nul(e) => Some(e),
|
|
Self::Utf8(e) => Some(e),
|
|
_ => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<TryFromIntError> for Error {
|
|
fn from(_value: TryFromIntError) -> Self {
|
|
Self::IntCast
|
|
}
|
|
}
|
|
|
|
impl From<io::Error> for Error {
|
|
fn from(value: io::Error) -> Self {
|
|
Self::Io(value)
|
|
}
|
|
}
|
|
|
|
impl From<ffi::NulError> for Error {
|
|
fn from(value: ffi::NulError) -> Self {
|
|
Self::Nul(value)
|
|
}
|
|
}
|
|
|
|
impl From<str::Utf8Error> for Error {
|
|
fn from(value: str::Utf8Error) -> Self {
|
|
Self::Utf8(value)
|
|
}
|
|
}
|
|
|
|
impl From<&str> for Error {
|
|
fn from(value: &str) -> Self {
|
|
Self::Other(value.to_string())
|
|
}
|
|
}
|
|
|
|
impl From<String> for Error {
|
|
fn from(value: String) -> Self {
|
|
Self::Other(value)
|
|
}
|
|
}
|
|
|
|
pub fn get_group_names() -> Result<Vec<String>, Error> {
|
|
let mut gids: Vec<libc::gid_t> = vec![0; 1];
|
|
unsafe {
|
|
let num = libc::getgroups(0, gids.as_mut_ptr());
|
|
gids = vec![0; num.try_into()?];
|
|
libc::getgroups(num, gids.as_mut_ptr());
|
|
}
|
|
let mut names = vec![];
|
|
for id in gids {
|
|
let name = unsafe {
|
|
let gr = libc::getgrgid(id);
|
|
if gr.is_null() {
|
|
id.to_string()
|
|
} else {
|
|
let name = (*gr).gr_name;
|
|
// if we don't take ownership here the OS can (and will)
|
|
// reuse the memory
|
|
CStr::from_ptr(name).to_str()?.to_string()
|
|
}
|
|
};
|
|
names.push(name);
|
|
}
|
|
Ok(names)
|
|
}
|