constructing header
This commit is contained in:
parent
bb3577f7b3
commit
f4012c8694
@ -95,11 +95,11 @@ const Corpus = struct {
|
|||||||
defer baseAllocator.free(user2groups);
|
defer baseAllocator.free(user2groups);
|
||||||
mem.set(ArrayListUnmanaged(u32), user2groups, ArrayListUnmanaged(u32){});
|
mem.set(ArrayListUnmanaged(u32), user2groups, ArrayListUnmanaged(u32){});
|
||||||
|
|
||||||
for (groups.items(.members)) |group_members, i| {
|
for (groups.items(.members)) |groupmembers, i| {
|
||||||
var members = try allocator.alloc(u32, group_members.count());
|
var members = try allocator.alloc(u32, groupmembers.count());
|
||||||
members.len = 0;
|
members.len = 0;
|
||||||
|
|
||||||
var it = group_members.iterator();
|
var it = groupmembers.iterator();
|
||||||
while (it.next()) |memberName| {
|
while (it.next()) |memberName| {
|
||||||
if (name2user.get(memberName.*)) |user_idx| {
|
if (name2user.get(memberName.*)) |user_idx| {
|
||||||
members.len += 1;
|
members.len += 1;
|
||||||
@ -148,7 +148,7 @@ pub fn shellSections(
|
|||||||
return popcon.toOwnedSections(max_shells);
|
return popcon.toOwnedSections(max_shells);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const UserGids = struct {
|
pub const AdditionalGids = struct {
|
||||||
// user index -> offset in blob
|
// user index -> offset in blob
|
||||||
idx2offset: []const u64,
|
idx2offset: []const u64,
|
||||||
// compressed user gids blob. A blob contains N <= users.len items,
|
// compressed user gids blob. A blob contains N <= users.len items,
|
||||||
@ -158,7 +158,7 @@ pub const UserGids = struct {
|
|||||||
// ... and the gid list is delta-compressed.
|
// ... and the gid list is delta-compressed.
|
||||||
blob: []const u8,
|
blob: []const u8,
|
||||||
|
|
||||||
pub fn deinit(self: *UserGids, allocator: Allocator) void {
|
pub fn deinit(self: *AdditionalGids, allocator: Allocator) void {
|
||||||
allocator.free(self.idx2offset);
|
allocator.free(self.idx2offset);
|
||||||
allocator.free(self.blob);
|
allocator.free(self.blob);
|
||||||
self.* = undefined;
|
self.* = undefined;
|
||||||
@ -168,7 +168,7 @@ pub const UserGids = struct {
|
|||||||
pub fn userGids(
|
pub fn userGids(
|
||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
corpus: *const Corpus,
|
corpus: *const Corpus,
|
||||||
) error{ OutOfMemory, Overflow }!UserGids {
|
) error{ OutOfMemory, Overflow }!AdditionalGids {
|
||||||
var blob = ArrayList(u8).init(allocator);
|
var blob = ArrayList(u8).init(allocator);
|
||||||
errdefer blob.deinit();
|
errdefer blob.deinit();
|
||||||
var idx2offset = try allocator.alloc(u64, corpus.users.len);
|
var idx2offset = try allocator.alloc(u64, corpus.users.len);
|
||||||
@ -198,13 +198,15 @@ pub fn userGids(
|
|||||||
try compress.appendUvarint(&blob, gid);
|
try compress.appendUvarint(&blob, gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
return UserGids{
|
return AdditionalGids{
|
||||||
.idx2offset = idx2offset,
|
.idx2offset = idx2offset,
|
||||||
.blob = blob.toOwnedSlice(),
|
.blob = blob.toOwnedSlice(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const UsersSection = struct {
|
pub const UsersSection = struct {
|
||||||
|
// number of users in this section
|
||||||
|
len: u32,
|
||||||
// user index -> offset in blob
|
// user index -> offset in blob
|
||||||
idx2offset: []const u32,
|
idx2offset: []const u32,
|
||||||
blob: []const u8,
|
blob: []const u8,
|
||||||
@ -219,7 +221,7 @@ pub const UsersSection = struct {
|
|||||||
pub fn usersSection(
|
pub fn usersSection(
|
||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
corpus: *const Corpus,
|
corpus: *const Corpus,
|
||||||
gids: *const UserGids,
|
gids: *const AdditionalGids,
|
||||||
shells: *const ShellSections,
|
shells: *const ShellSections,
|
||||||
) error{ OutOfMemory, Overflow, InvalidRecord }!UsersSection {
|
) error{ OutOfMemory, Overflow, InvalidRecord }!UsersSection {
|
||||||
var idx2offset = try allocator.alloc(u32, corpus.users.len);
|
var idx2offset = try allocator.alloc(u32, corpus.users.len);
|
||||||
@ -244,6 +246,7 @@ pub fn usersSection(
|
|||||||
try pad.arrayList(&blob, PackedUser.alignment_bits);
|
try pad.arrayList(&blob, PackedUser.alignment_bits);
|
||||||
}
|
}
|
||||||
return UsersSection{
|
return UsersSection{
|
||||||
|
.len = @intCast(u32, corpus.users.len),
|
||||||
.idx2offset = idx2offset,
|
.idx2offset = idx2offset,
|
||||||
.blob = blob.toOwnedSlice(),
|
.blob = blob.toOwnedSlice(),
|
||||||
};
|
};
|
||||||
@ -303,6 +306,8 @@ pub fn groupMembers(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub const GroupsSection = struct {
|
pub const GroupsSection = struct {
|
||||||
|
// number of groups in this section
|
||||||
|
len: u32,
|
||||||
// group index -> offset in blob
|
// group index -> offset in blob
|
||||||
idx2offset: []const u32,
|
idx2offset: []const u32,
|
||||||
blob: []const u8,
|
blob: []const u8,
|
||||||
@ -342,6 +347,7 @@ pub fn groupsSection(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return GroupsSection{
|
return GroupsSection{
|
||||||
|
.len = @intCast(u32, corpus.groups.len),
|
||||||
.idx2offset = idx2offset,
|
.idx2offset = idx2offset,
|
||||||
.blob = blob.toOwnedSlice(),
|
.blob = blob.toOwnedSlice(),
|
||||||
};
|
};
|
||||||
@ -416,8 +422,8 @@ pub const AllSections = struct {
|
|||||||
users: UsersSection,
|
users: UsersSection,
|
||||||
shell_sections: ShellSections,
|
shell_sections: ShellSections,
|
||||||
shell_reader: ShellReader,
|
shell_reader: ShellReader,
|
||||||
user_gids: UserGids,
|
additional_gids: AdditionalGids,
|
||||||
group_members: GroupMembers,
|
groupmembers: GroupMembers,
|
||||||
groups: GroupsSection,
|
groups: GroupsSection,
|
||||||
idx_gid2group: []const u32,
|
idx_gid2group: []const u32,
|
||||||
idx_groupname2group: []const u32,
|
idx_groupname2group: []const u32,
|
||||||
@ -449,16 +455,16 @@ pub const AllSections = struct {
|
|||||||
var shell_sections = try shellSections(allocator, corpus);
|
var shell_sections = try shellSections(allocator, corpus);
|
||||||
errdefer shell_sections.deinit();
|
errdefer shell_sections.deinit();
|
||||||
|
|
||||||
var user_gids = try userGids(allocator, corpus);
|
var additional_gids = try userGids(allocator, corpus);
|
||||||
errdefer user_gids.deinit(allocator);
|
errdefer additional_gids.deinit(allocator);
|
||||||
|
|
||||||
var users = try usersSection(allocator, corpus, &user_gids, &shell_sections);
|
var users = try usersSection(allocator, corpus, &additional_gids, &shell_sections);
|
||||||
errdefer users.deinit(allocator);
|
errdefer users.deinit(allocator);
|
||||||
|
|
||||||
var group_members = try groupMembers(allocator, corpus, users.idx2offset);
|
var groupmembers = try groupMembers(allocator, corpus, users.idx2offset);
|
||||||
errdefer group_members.deinit(allocator);
|
errdefer groupmembers.deinit(allocator);
|
||||||
|
|
||||||
var groups = try groupsSection(allocator, corpus, group_members.idx2offset);
|
var groups = try groupsSection(allocator, corpus, groupmembers.idx2offset);
|
||||||
errdefer groups.deinit(allocator);
|
errdefer groups.deinit(allocator);
|
||||||
|
|
||||||
var idx_gid2group = try bdzIdx(u32, allocator, bdz_gid, gids, groups.idx2offset);
|
var idx_gid2group = try bdzIdx(u32, allocator, bdz_gid, gids, groups.idx2offset);
|
||||||
@ -474,18 +480,18 @@ pub const AllSections = struct {
|
|||||||
errdefer allocator.free(idx_name2user);
|
errdefer allocator.free(idx_name2user);
|
||||||
|
|
||||||
const header = Header{
|
const header = Header{
|
||||||
.nblocks_shell_blob = undefined,
|
.nblocks_shell_blob = nblocks(u8, shell_sections.blob.constSlice()),
|
||||||
.num_shells = undefined,
|
.num_shells = shell_sections.len,
|
||||||
.num_groups = undefined,
|
.num_groups = groups.len,
|
||||||
.num_users = undefined,
|
.num_users = users.len,
|
||||||
.nblocks_bdz_gid = undefined,
|
.nblocks_bdz_gid = nblocks(u32, bdz_gid),
|
||||||
.nblocks_bdz_groupname = undefined,
|
.nblocks_bdz_groupname = nblocks(u32, bdz_groupname),
|
||||||
.nblocks_bdz_uid = undefined,
|
.nblocks_bdz_uid = nblocks(u32, bdz_uid),
|
||||||
.nblocks_bdz_username = undefined,
|
.nblocks_bdz_username = nblocks(u32, bdz_username),
|
||||||
.nblocks_groups = undefined,
|
.nblocks_groups = nblocks(u64, groups.blob),
|
||||||
.nblocks_users = undefined,
|
.nblocks_users = nblocks(u64, users.blob),
|
||||||
.nblocks_groupmembers = undefined,
|
.nblocks_groupmembers = nblocks(u64, groupmembers.blob),
|
||||||
.nblocks_additional_gids = undefined,
|
.nblocks_additional_gids = nblocks(u64, additional_gids.blob),
|
||||||
};
|
};
|
||||||
|
|
||||||
return AllSections{
|
return AllSections{
|
||||||
@ -499,9 +505,9 @@ pub const AllSections = struct {
|
|||||||
mem.sliceAsBytes(shell_sections.index.constSlice()),
|
mem.sliceAsBytes(shell_sections.index.constSlice()),
|
||||||
mem.sliceAsBytes(shell_sections.blob.constSlice()),
|
mem.sliceAsBytes(shell_sections.blob.constSlice()),
|
||||||
),
|
),
|
||||||
.user_gids = user_gids,
|
.additional_gids = additional_gids,
|
||||||
.users = users,
|
.users = users,
|
||||||
.group_members = group_members,
|
.groupmembers = groupmembers,
|
||||||
.groups = groups,
|
.groups = groups,
|
||||||
.idx_gid2group = idx_gid2group,
|
.idx_gid2group = idx_gid2group,
|
||||||
.idx_groupname2group = idx_groupname2group,
|
.idx_groupname2group = idx_groupname2group,
|
||||||
@ -517,9 +523,9 @@ pub const AllSections = struct {
|
|||||||
self.allocator.free(self.bdz_uid);
|
self.allocator.free(self.bdz_uid);
|
||||||
self.allocator.free(self.bdz_username);
|
self.allocator.free(self.bdz_username);
|
||||||
self.shell_sections.deinit();
|
self.shell_sections.deinit();
|
||||||
self.user_gids.deinit(self.allocator);
|
self.additional_gids.deinit(self.allocator);
|
||||||
self.users.deinit(self.allocator);
|
self.users.deinit(self.allocator);
|
||||||
self.group_members.deinit(self.allocator);
|
self.groupmembers.deinit(self.allocator);
|
||||||
self.groups.deinit(self.allocator);
|
self.groups.deinit(self.allocator);
|
||||||
self.allocator.free(self.idx_gid2group);
|
self.allocator.free(self.idx_gid2group);
|
||||||
self.allocator.free(self.idx_groupname2group);
|
self.allocator.free(self.idx_groupname2group);
|
||||||
@ -657,10 +663,10 @@ test "test groups, group members and users" {
|
|||||||
var sections = try AllSections.init(allocator, &corpus);
|
var sections = try AllSections.init(allocator, &corpus);
|
||||||
defer sections.deinit();
|
defer sections.deinit();
|
||||||
|
|
||||||
const blob = sections.group_members.blob;
|
const blob = sections.groupmembers.blob;
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
while (i < corpus.groups.len) : (i += 1) {
|
while (i < corpus.groups.len) : (i += 1) {
|
||||||
const offset = sections.group_members.idx2offset[i];
|
const offset = sections.groupmembers.idx2offset[i];
|
||||||
var vit = try compress.VarintSliceIterator(blob[offset..]);
|
var vit = try compress.VarintSliceIterator(blob[offset..]);
|
||||||
var it = compress.DeltaDecompressionIterator(&vit);
|
var it = compress.DeltaDecompressionIterator(&vit);
|
||||||
for (corpus.group2users[i]) |user_idx| {
|
for (corpus.group2users[i]) |user_idx| {
|
||||||
@ -690,18 +696,18 @@ test "userGids" {
|
|||||||
var corpus = try testCorpus(allocator);
|
var corpus = try testCorpus(allocator);
|
||||||
defer corpus.deinit();
|
defer corpus.deinit();
|
||||||
|
|
||||||
var user_gids = try userGids(allocator, &corpus);
|
var additional_gids = try userGids(allocator, &corpus);
|
||||||
defer user_gids.deinit(allocator);
|
defer additional_gids.deinit(allocator);
|
||||||
|
|
||||||
var user_idx: usize = 0;
|
var user_idx: usize = 0;
|
||||||
while (user_idx < corpus.users.len) : (user_idx += 1) {
|
while (user_idx < corpus.users.len) : (user_idx += 1) {
|
||||||
const groups = corpus.user2groups[user_idx];
|
const groups = corpus.user2groups[user_idx];
|
||||||
const offset = user_gids.idx2offset[user_idx];
|
const offset = additional_gids.idx2offset[user_idx];
|
||||||
if (groups.len == 0) {
|
if (groups.len == 0) {
|
||||||
try testing.expect(offset == 0);
|
try testing.expect(offset == 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var vit = try compress.VarintSliceIterator(user_gids.blob[offset..]);
|
var vit = try compress.VarintSliceIterator(additional_gids.blob[offset..]);
|
||||||
var it = compress.DeltaDecompressionIterator(&vit);
|
var it = compress.DeltaDecompressionIterator(&vit);
|
||||||
try testing.expectEqual(it.remaining(), groups.len);
|
try testing.expectEqual(it.remaining(), groups.len);
|
||||||
var i: u64 = 0;
|
var i: u64 = 0;
|
||||||
|
@ -38,6 +38,8 @@ pub const ShellWriter = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const ShellSections = struct {
|
pub const ShellSections = struct {
|
||||||
|
// len is the number of shells in this section.
|
||||||
|
len: u8,
|
||||||
// index points the i'th shell to it's offset in blob. The last
|
// index points the i'th shell to it's offset in blob. The last
|
||||||
// byte of the i'th shell is index[i+1].
|
// byte of the i'th shell is index[i+1].
|
||||||
index: BoundedArray(u16, max_shells),
|
index: BoundedArray(u16, max_shells),
|
||||||
@ -55,6 +57,7 @@ pub const ShellWriter = struct {
|
|||||||
shells: BoundedArray([]const u8, max_shells),
|
shells: BoundedArray([]const u8, max_shells),
|
||||||
) error{ Overflow, OutOfMemory }!ShellSections {
|
) error{ Overflow, OutOfMemory }!ShellSections {
|
||||||
var self = ShellSections{
|
var self = ShellSections{
|
||||||
|
.len = @intCast(u8, shells.len),
|
||||||
.index = try BoundedArray(u16, max_shells).init(shells.len),
|
.index = try BoundedArray(u16, max_shells).init(shells.len),
|
||||||
.blob = try BoundedArray(u8, (max_shells + 1) * max_shell_len).init(0),
|
.blob = try BoundedArray(u8, (max_shells + 1) * max_shell_len).init(0),
|
||||||
.shell2idx = StringHashMap(u8).init(allocator),
|
.shell2idx = StringHashMap(u8).init(allocator),
|
||||||
|
Loading…
Reference in New Issue
Block a user