Function posixGetUserInfo [src]

TODO this reads /etc/passwd. But sometimes the user/id mapping is in something else like NIS, AD, etc. See man nss or look at an strace for id myuser.

Prototype

pub fn posixGetUserInfo(name: []const u8) !UserInfo

Parameters

name: []const u8

Source

pub fn posixGetUserInfo(name: []const u8) !UserInfo { const file = try std.fs.openFileAbsolute("/etc/passwd", .{}); defer file.close(); const reader = file.reader(); const State = enum { Start, WaitForNextLine, SkipPassword, ReadUserId, ReadGroupId, }; var buf: [std.heap.page_size_min]u8 = undefined; var name_index: usize = 0; var state = State.Start; var uid: posix.uid_t = 0; var gid: posix.gid_t = 0; while (true) { const amt_read = try reader.read(buf[0..]); for (buf[0..amt_read]) |byte| { switch (state) { .Start => switch (byte) { ':' => { state = if (name_index == name.len) State.SkipPassword else State.WaitForNextLine; }, '\n' => return error.CorruptPasswordFile, else => { if (name_index == name.len or name[name_index] != byte) { state = .WaitForNextLine; } name_index += 1; }, }, .WaitForNextLine => switch (byte) { '\n' => { name_index = 0; state = .Start; }, else => continue, }, .SkipPassword => switch (byte) { '\n' => return error.CorruptPasswordFile, ':' => { state = .ReadUserId; }, else => continue, }, .ReadUserId => switch (byte) { ':' => { state = .ReadGroupId; }, '\n' => return error.CorruptPasswordFile, else => { const digit = switch (byte) { '0'...'9' => byte - '0', else => return error.CorruptPasswordFile, }; { const ov = @mulWithOverflow(uid, 10); if (ov[1] != 0) return error.CorruptPasswordFile; uid = ov[0]; } { const ov = @addWithOverflow(uid, digit); if (ov[1] != 0) return error.CorruptPasswordFile; uid = ov[0]; } }, }, .ReadGroupId => switch (byte) { '\n', ':' => { return UserInfo{ .uid = uid, .gid = gid, }; }, else => { const digit = switch (byte) { '0'...'9' => byte - '0', else => return error.CorruptPasswordFile, }; { const ov = @mulWithOverflow(gid, 10); if (ov[1] != 0) return error.CorruptPasswordFile; gid = ov[0]; } { const ov = @addWithOverflow(gid, digit); if (ov[1] != 0) return error.CorruptPasswordFile; gid = ov[0]; } }, }, } } if (amt_read < buf.len) return error.UserNotFound; } }