Skip to content

Instantly share code, notes, and snippets.

@jgarzik
Created April 17, 2024 01:45
Show Gist options
  • Save jgarzik/6406e400b16d6870b28f0bd80a5c02e9 to your computer and use it in GitHub Desktop.
Save jgarzik/6406e400b16d6870b28f0bd80a5c02e9 to your computer and use it in GitHub Desktop.
enumerate groups, Take One (chatGPT edition)
extern crate libc;
use libc::{group, setgrent, getgrent, endgrent, gid_t};
use std::ffi::CStr;
use std::ptr;
struct Group {
name: String,
passwd: String,
gid: gid_t,
members: Vec<String>,
}
fn load_group_db() -> Vec<Group> {
let mut groups = Vec::new();
unsafe { setgrent() };
loop {
unsafe {
let group_ptr = getgrent();
if group_ptr.is_null() {
break;
}
let group = &*group_ptr; // Dereference once and use it safely within the block
let name = CStr::from_ptr(group.gr_name).to_string_lossy().to_string();
let passwd = CStr::from_ptr(group.gr_passwd).to_string_lossy().to_string();
let gid = group.gr_gid;
let mut members = Vec::new();
let mut member_ptr = group.gr_mem;
while !(*member_ptr).is_null() {
let member_c_str = CStr::from_ptr(*member_ptr);
members.push(member_c_str.to_string_lossy().to_string());
member_ptr = member_ptr.add(1); // Correctly advance to the next pointer
}
groups.push(Group {
name,
passwd,
gid,
members,
});
}
}
unsafe { endgrent() };
groups
}
fn main() {
let groups = load_group_db();
for group in groups {
println!("Group: {} (GID: {})", group.name, group.gid);
println!("Members: {:?}", group.members);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment