commit 6e0f963175c5d1efac3ef8d4091927029865185d parent ea4a0455414ebf3ce0f2e7ebaccc426f0f2f5a35 Author: Willow Barraco <contact@willowbarraco.fr> Date: Mon, 25 Mar 2024 11:58:04 +0100 unix::passwd: implement getgroups Signed-off-by: Willow Barraco <contact@willowbarraco.fr> Diffstat:
M | unix/passwd/group.ha | | | 44 | ++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 44 insertions(+), 0 deletions(-)
diff --git a/unix/passwd/group.ha b/unix/passwd/group.ha @@ -99,6 +99,50 @@ export fn getgroup(name: str) (grent | void) = { }; }; +// Looks up groups by user name in a Unix-like group file. It expects a such +// file at /etc/group. Aborts if that file doesn't exist or is not properly +// formatted. +// +// See [[nextgr]] for low-level parsing API. +export fn getgroups(name: str) []grent = { + let file = match (os::open("/etc/group")) { + case let f: io::file => + yield f; + case => + abort("Unable to open /etc/group"); + }; + defer io::close(file)!; + + let groups = []: []grent; + + let rbuf: [os::BUFSZ]u8 = [0...]; + let strm = bufio::init(file, rbuf, []); + for (true) { + let ent = match (nextgr(&strm)) { + case let e: grent => + yield e; + case io::EOF => + break; + case => + abort("Invalid entry in /etc/group"); + }; + + let matched = false; + for (let i = 0z; i < len(ent.userlist); i += 1) { + if (ent.userlist[i] == name) { + matched = true; + append(groups, ent); + break; + }; + }; + if (!matched) { + grent_finish(&ent); + }; + }; + + return groups; +}; + // Looks up a group by ID in a Unix-like group file. It expects a such file at // /etc/group. Aborts if that file doesn't exist or is not properly formatted. //