wip -- turbo-getent
This commit is contained in:
parent
9a7447eaa1
commit
e116dd0c28
69
src/DB.zig
69
src/DB.zig
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue