group members are now slices
This commit is contained in:
parent
88d88af111
commit
34049d13f0
@ -82,12 +82,11 @@ pub fn init(
|
||||
mem.set(ArrayListUnmanaged(u32), user2groups, ArrayListUnmanaged(u32){});
|
||||
|
||||
for (groups.items(.members)) |groupmembers, i| {
|
||||
var members = try allocator.alloc(u32, groupmembers.count());
|
||||
var members = try allocator.alloc(u32, groupmembers.len);
|
||||
members.len = 0;
|
||||
|
||||
var it = groupmembers.iterator();
|
||||
while (it.next()) |member_name| {
|
||||
if (name2user.get(member_name.*)) |user_idx| {
|
||||
for (groupmembers) |member_name| {
|
||||
if (name2user.get(member_name)) |user_idx| {
|
||||
members.len += 1;
|
||||
members[members.len - 1] = user_idx;
|
||||
try user2groups[user_idx].append(allocator, @intCast(u32, i));
|
||||
@ -204,29 +203,10 @@ pub fn testCorpus(allocator: Allocator) !Corpus {
|
||||
.shell = "/usr/sbin/nologin",
|
||||
} };
|
||||
|
||||
var members0 = try someMembers(
|
||||
allocator,
|
||||
&[_][]const u8{"root"},
|
||||
);
|
||||
defer members0.deinit();
|
||||
|
||||
var members1 = try someMembers(
|
||||
allocator,
|
||||
&[_][]const u8{"vidmantas"},
|
||||
);
|
||||
defer members1.deinit();
|
||||
|
||||
var members2 = try someMembers(
|
||||
allocator,
|
||||
&[_][]const u8{ "svc-bar", "vidmantas" },
|
||||
);
|
||||
defer members2.deinit();
|
||||
|
||||
var members3 = try someMembers(
|
||||
allocator,
|
||||
&[_][]const u8{ "svc-bar", "Name" ** 8, "vidmantas", "root" },
|
||||
);
|
||||
defer members3.deinit();
|
||||
var members0 = &[_][]const u8{"root"};
|
||||
var members1 = &[_][]const u8{"vidmantas"};
|
||||
var members2 = &[_][]const u8{ "svc-bar", "vidmantas" };
|
||||
var members3 = &[_][]const u8{ "svc-bar", "Name" ** 8, "vidmantas", "root" };
|
||||
|
||||
const groups = [_]Group{
|
||||
Group{ .gid = 0, .name = "root", .members = members0 },
|
||||
|
15
lib/DB.zig
15
lib/DB.zig
@ -218,6 +218,21 @@ pub fn fromBytes(buf: []align(8) const u8) InvalidHeader!DB {
|
||||
return result;
|
||||
}
|
||||
|
||||
// getgrtnam returns a Group entry by name
|
||||
fn getgrnam(self: *const DB, name: []const u8) ?Group {
|
||||
const idx = bdz.search(self.bdz_groupname);
|
||||
const offset = self.idx_groupname2group[idx];
|
||||
const entry = PackedGroup.fromBytes(self.groups[offset..]);
|
||||
if (!mem.eql(name, entry.group.name()))
|
||||
return null;
|
||||
|
||||
return Group{
|
||||
.name = name,
|
||||
.gid = entry.group.gid(),
|
||||
.members = null,
|
||||
};
|
||||
}
|
||||
|
||||
fn shellSections(
|
||||
allocator: Allocator,
|
||||
corpus: *const Corpus,
|
||||
|
@ -2,79 +2,70 @@ const std = @import("std");
|
||||
|
||||
const mem = std.mem;
|
||||
const Allocator = mem.Allocator;
|
||||
const BufSet = std.BufSet;
|
||||
|
||||
const Group = @This();
|
||||
|
||||
gid: u32,
|
||||
name: []const u8,
|
||||
members: BufSet,
|
||||
members: []const []const u8,
|
||||
_members_buf: []const u8 = undefined,
|
||||
|
||||
pub fn clone(self: *const Group, allocator: Allocator) Allocator.Error!Group {
|
||||
var name = try allocator.dupe(u8, self.name);
|
||||
const total_members_len = blk: {
|
||||
var sum: usize = 0;
|
||||
for (self.members) |member| sum += member.len;
|
||||
break :blk sum;
|
||||
};
|
||||
var members = try allocator.alloc([]const u8, self.members.len);
|
||||
errdefer allocator.free(members);
|
||||
members.len = self.members.len;
|
||||
|
||||
var buf = try allocator.alloc(u8, total_members_len);
|
||||
errdefer allocator.free(buf);
|
||||
buf.len = 0;
|
||||
|
||||
for (self.members) |member, i| {
|
||||
const old_len = buf.len;
|
||||
buf.len += member.len;
|
||||
mem.copy(u8, buf[old_len..], member);
|
||||
members[i] = buf[old_len..buf.len];
|
||||
}
|
||||
|
||||
return Group{
|
||||
.gid = self.gid,
|
||||
.name = name,
|
||||
.members = try self.members.cloneWithAllocator(allocator),
|
||||
.name = try allocator.dupe(u8, self.name),
|
||||
.members = members,
|
||||
._members_buf = buf,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Group, allocator: Allocator) void {
|
||||
allocator.free(self.name);
|
||||
self.members.deinit();
|
||||
allocator.free(self.members);
|
||||
allocator.free(self._members_buf);
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
// someMembers constructs a bufset from an allocator and a list of strings.
|
||||
pub fn someMembers(
|
||||
allocator: Allocator,
|
||||
members: []const []const u8,
|
||||
) Allocator.Error!BufSet {
|
||||
var bufset = BufSet.init(allocator);
|
||||
errdefer bufset.deinit();
|
||||
for (members) |member|
|
||||
try bufset.insert(member);
|
||||
return bufset;
|
||||
}
|
||||
|
||||
// cloneArray clones an array of strings. This may be needed
|
||||
// to change members to []const []const u8
|
||||
fn cloneArray(allocator: Allocator, arr: []const []const u8) error{OutOfMemory}![]const []const u8 {
|
||||
const total_len = blk: {
|
||||
var sum: usize = 0;
|
||||
for (arr) |elem| sum += elem.len;
|
||||
break :blk sum;
|
||||
};
|
||||
var buf = try allocator.alloc(u8, total_len);
|
||||
var ret = try allocator.alloc([]const u8, arr.len);
|
||||
ret.len = arr.len;
|
||||
for (arr) |elem, i| {
|
||||
const old_len = buf.len;
|
||||
mem.copy(u8, buf[old_len..], elem);
|
||||
ret[i] = buf[old_len .. old_len + elem.len];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
const testing = std.testing;
|
||||
|
||||
test "Group.clone" {
|
||||
var allocator = testing.allocator;
|
||||
var arena = std.heap.ArenaAllocator.init(allocator);
|
||||
defer arena.deinit();
|
||||
// TODO: how to do this on stack?
|
||||
var member1 = try testing.allocator.dupe(u8, "member1");
|
||||
defer testing.allocator.free(member1);
|
||||
|
||||
var members = BufSet.init(allocator);
|
||||
try members.insert("member1");
|
||||
try members.insert("member2");
|
||||
defer members.deinit();
|
||||
var group = Group{
|
||||
.gid = 1,
|
||||
.name = "foo",
|
||||
.members = &[_][]const u8{ member1, "member2" },
|
||||
};
|
||||
|
||||
var cloned = try members.cloneWithAllocator(arena.allocator());
|
||||
var cloned = try group.clone(testing.allocator);
|
||||
defer cloned.deinit(testing.allocator);
|
||||
|
||||
cloned.remove("member1");
|
||||
try cloned.insert("member4");
|
||||
try testing.expect(members.contains("member1"));
|
||||
try testing.expect(!members.contains("member4"));
|
||||
|
||||
try testing.expect(!cloned.contains("member1"));
|
||||
try testing.expect(cloned.contains("member4"));
|
||||
group.gid = 2;
|
||||
group.name = "bar";
|
||||
member1[0] = 'x';
|
||||
try testing.expectEqual(cloned.gid, 1);
|
||||
try testing.expectEqualSlices(u8, cloned.name, "foo");
|
||||
try testing.expectEqualSlices(u8, cloned.members[0], "member1");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user