wip -- turbo-getent

This commit is contained in:
Motiejus Jakštys 2022-07-11 15:35:46 +03:00
parent 9a7447eaa1
commit e116dd0c28
3 changed files with 71 additions and 21 deletions

View File

@ -301,6 +301,23 @@ pub fn packCGroupNoMembers(group: PackedGroup, buf: []u8) error{BufferTooSmall}!
};
}
const GroupMembersIter = struct {
it: compress.DeltaDecompressionIterator,
};
pub fn groupMembersIter(vit: *compress.varintSliceIterator) GroupMembersIter {
return GroupMembersIter{
.it = compress.deltaDecompressionIterator(vit),
};
}
//pub fn groupMembersIter(members_slice: []const u8) GroupMembersIter {
// var vit = compress.VarintSliceIteratorMust(members_slice);
// return GroupMembersIter{
// .it = compress.deltaDecompressionIterator(&vit),
// };
//}
// dumps PackedGroup to []u8 and returns a CGroup.
pub fn packCGroup(self: *const DB, group: PackedGroup, buf: []u8) error{BufferTooSmall}!CGroup {
const members_slice = self.groupmembers[group.members_offset..];
@ -314,8 +331,14 @@ pub fn packCGroup(self: *const DB, group: PackedGroup, buf: []u8) error{BufferTo
var buf_offset: usize = ptr_end;
var it = compress.deltaDecompressionIterator(&vit);
var members = groupMembersIter(&vit);
_ = members;
_ = it;
var i: usize = 0;
std.debug.print("\n", .{});
while (it.nextMust()) |member_offset| : (i += 1) {
std.debug.print("got offset: {d}\n", .{member_offset});
const entry = PackedUser.fromBytes(self.users[member_offset << 3 ..]);
const start = buf_offset;
const name = entry.user.name();
@ -342,6 +365,26 @@ pub fn packCGroup(self: *const DB, group: PackedGroup, buf: []u8) error{BufferTo
};
}
pub fn getGroupByName(self: *const DB, name: []const u8) ?PackedGroup {
const idx = bdz.search(self.bdz_groupname, name);
if (idx >= self.header.num_groups) return null;
const offset = self.idx_groupname2group[idx];
const nbits = PackedGroup.alignment_bits;
const group = PackedGroup.fromBytes(self.groups[offset << nbits ..]).group;
if (!mem.eql(u8, name, group.name())) return null;
return group;
}
pub fn getGroupByGid(self: *const DB, gid: u32) ?PackedGroup {
const idx = bdz.search_u32(self.bdz_gid, gid);
if (idx >= self.header.num_groups) return null;
const offset = self.idx_gid2group[idx];
const nbits = PackedGroup.alignment_bits;
const group = PackedGroup.fromBytes(self.groups[offset << nbits ..]).group;
if (gid != group.gid()) return null;
return group;
}
// get a CGroup entry by name.
pub fn getgrnam(
self: *const DB,
@ -349,16 +392,11 @@ pub fn getgrnam(
buf: []u8,
omit_members: bool,
) error{BufferTooSmall}!?CGroup {
const idx = bdz.search(self.bdz_groupname, name);
if (idx >= self.header.num_groups) return null;
const offset = self.idx_groupname2group[idx];
const nbits = PackedGroup.alignment_bits;
const group = PackedGroup.fromBytes(self.groups[offset << nbits ..]).group;
if (!mem.eql(u8, name, group.name())) return null;
return if (omit_members)
try packCGroupNoMembers(group, buf)
const group = self.getGroupByName(name) orelse return null;
if (omit_members)
return try packCGroupNoMembers(group, buf)
else
try self.packCGroup(group, buf);
return try self.packCGroup(group, buf);
}
// get a CGroup entry by it's gid.
@ -368,16 +406,11 @@ pub fn getgrgid(
buf: []u8,
omit_members: bool,
) error{BufferTooSmall}!?CGroup {
const idx = bdz.search_u32(self.bdz_gid, gid);
if (idx >= self.header.num_groups) return null;
const offset = self.idx_gid2group[idx];
const nbits = PackedGroup.alignment_bits;
const group = PackedGroup.fromBytes(self.groups[offset << nbits ..]).group;
if (gid != group.gid()) return null;
return if (omit_members)
try packCGroupNoMembers(group, buf)
const group = self.getGroupByGid(gid) orelse return null;
if (omit_members)
return try packCGroupNoMembers(group, buf)
else
try self.packCGroup(group, buf);
return try self.packCGroup(group, buf);
}
fn pushStr(str: []const u8, buf: []u8, offset: *usize) [*:0]const u8 {

View File

@ -103,7 +103,7 @@ pub fn putUvarint(buf: []u8, x: u64) usize {
// VarintSliceIterator iterates over varint-encoded slice.
// The first element is the length of the slice, in decoded numbers.
const varintSliceIterator = struct {
pub const varintSliceIterator = struct {
remaining: usize,
arr: []const u8,
idx: usize,

View File

@ -122,7 +122,8 @@ fn passwd(stdout: anytype, db: *const DB, keys: []const [*:0]const u8) u8 {
}
fn passwd_all(stdout: anytype, db: *const DB) u8 {
var it = PackedUser.iterator(db.users, db.header.num_users, db.shellReader());
const shell_reader = db.shellReader();
var it = PackedUser.iterator(db.users, db.header.num_users, shell_reader);
while (it.next()) |packed_user| {
const line = packed_user.toUser(db.shellReader()).toLine();
stdout.writeAll(line.constSlice()) catch return 3;
@ -133,8 +134,24 @@ fn passwd_all(stdout: anytype, db: *const DB) u8 {
fn group(stdout: anytype, db: *const DB, keys: []const [*:0]const u8) u8 {
if (keys.len == 0)
return group_all(stdout, db);
var some_notfound = false;
for (keys) |key| {
const keyZ = mem.span(key);
const maybe_packed_group = if (fmt.parseUnsigned(u32, keyZ, 10)) |gid|
db.getGroupByGid(gid)
else |_|
db.getGroupByName(keyZ);
const g = maybe_packed_group orelse {
some_notfound = true;
continue;
};
// not converting to Group to avoid memory allocations.
stdout.print("{s}:x:{d}:", .{ g.name(), g.gid() }) catch return 3;
}
return if (some_notfound) 2 else 0;
}