refactor libnss.zig
This commit is contained in:
parent
98db4ce0b2
commit
df14c1fc67
@ -280,7 +280,7 @@ pub fn fromBytes(buf: []align(8) const u8) InvalidHeader!DB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// dumps PackedGroup to []u8 and returns a CGroup.
|
// dumps PackedGroup to []u8 and returns a CGroup.
|
||||||
fn getGroup(self: *const DB, group: PackedGroup, buf: []u8) error{BufferTooSmall}!CGroup {
|
pub fn getGroup(self: *const DB, group: PackedGroup, buf: []u8) error{BufferTooSmall}!CGroup {
|
||||||
const members_slice = self.groupmembers[group.members_offset..];
|
const members_slice = self.groupmembers[group.members_offset..];
|
||||||
var vit = compress.VarintSliceIteratorMust(members_slice);
|
var vit = compress.VarintSliceIteratorMust(members_slice);
|
||||||
const num_members = vit.remaining;
|
const num_members = vit.remaining;
|
||||||
|
143
src/libnss.zig
143
src/libnss.zig
@ -108,20 +108,21 @@ export fn _nss_turbo_getpwuid_r(
|
|||||||
buflen: usize,
|
buflen: usize,
|
||||||
errnop: *c_int,
|
errnop: *c_int,
|
||||||
) c.enum_nss_status {
|
) c.enum_nss_status {
|
||||||
const db = getDb(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
const db = getDBErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
||||||
if (db.getpwuid(uid, buffer[0..buflen])) |maybe_cuser| {
|
|
||||||
if (maybe_cuser) |cuser| {
|
var cuser = db.getpwuid(uid, buffer[0..buflen]) catch |err| switch (err) {
|
||||||
passwd.* = cuser;
|
|
||||||
return c.NSS_STATUS_SUCCESS;
|
|
||||||
} else {
|
|
||||||
errnop.* = @enumToInt(os.E.NOENT);
|
|
||||||
return c.NSS_STATUS_NOTFOUND;
|
|
||||||
}
|
|
||||||
} else |err| switch (err) {
|
|
||||||
error.BufferTooSmall => {
|
error.BufferTooSmall => {
|
||||||
errnop.* = @enumToInt(os.E.RANGE);
|
errnop.* = @enumToInt(os.E.RANGE);
|
||||||
return c.NSS_STATUS_TRYAGAIN;
|
return c.NSS_STATUS_TRYAGAIN;
|
||||||
},
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (cuser) |got| {
|
||||||
|
passwd.* = got;
|
||||||
|
return c.NSS_STATUS_SUCCESS;
|
||||||
|
} else {
|
||||||
|
errnop.* = @enumToInt(os.E.NOENT);
|
||||||
|
return c.NSS_STATUS_NOTFOUND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,21 +133,23 @@ export fn _nss_turbo_getpwnam_r(
|
|||||||
buflen: usize,
|
buflen: usize,
|
||||||
errnop: *c_int,
|
errnop: *c_int,
|
||||||
) c.enum_nss_status {
|
) c.enum_nss_status {
|
||||||
const db = getDb(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
const db = getDBErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
||||||
const nameSlice = mem.sliceTo(name, 0);
|
const nameSlice = mem.sliceTo(name, 0);
|
||||||
if (db.getpwnam(nameSlice, buffer[0..buflen])) |maybe_cuser| {
|
|
||||||
if (maybe_cuser) |cuser| {
|
var buf = buffer[0..buflen];
|
||||||
passwd.* = cuser;
|
const cuser = db.getpwnam(nameSlice, buf) catch |err| switch (err) {
|
||||||
return c.NSS_STATUS_SUCCESS;
|
|
||||||
} else {
|
|
||||||
errnop.* = @enumToInt(os.E.NOENT);
|
|
||||||
return c.NSS_STATUS_NOTFOUND;
|
|
||||||
}
|
|
||||||
} else |err| switch (err) {
|
|
||||||
error.BufferTooSmall => {
|
error.BufferTooSmall => {
|
||||||
errnop.* = @enumToInt(os.E.RANGE);
|
errnop.* = @enumToInt(os.E.RANGE);
|
||||||
return c.NSS_STATUS_TRYAGAIN;
|
return c.NSS_STATUS_TRYAGAIN;
|
||||||
},
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (cuser) |got| {
|
||||||
|
passwd.* = got;
|
||||||
|
return c.NSS_STATUS_SUCCESS;
|
||||||
|
} else {
|
||||||
|
errnop.* = @enumToInt(os.E.NOENT);
|
||||||
|
return c.NSS_STATUS_NOTFOUND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,20 +160,20 @@ export fn _nss_turbo_getgrgid_r(
|
|||||||
buflen: usize,
|
buflen: usize,
|
||||||
errnop: *c_int,
|
errnop: *c_int,
|
||||||
) c.enum_nss_status {
|
) c.enum_nss_status {
|
||||||
const db = getDb(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
const db = getDBErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
||||||
if (db.getgrgid(gid, buffer[0..buflen])) |maybe_cgroup| {
|
var cgroup = db.getgrgid(gid, buffer[0..buflen]) catch |err| switch (err) {
|
||||||
if (maybe_cgroup) |cgroup| {
|
|
||||||
gr.* = cgroup;
|
|
||||||
return c.NSS_STATUS_SUCCESS;
|
|
||||||
} else {
|
|
||||||
errnop.* = @enumToInt(os.E.NOENT);
|
|
||||||
return c.NSS_STATUS_NOTFOUND;
|
|
||||||
}
|
|
||||||
} else |err| switch (err) {
|
|
||||||
error.BufferTooSmall => {
|
error.BufferTooSmall => {
|
||||||
errnop.* = @enumToInt(os.E.RANGE);
|
errnop.* = @enumToInt(os.E.RANGE);
|
||||||
return c.NSS_STATUS_TRYAGAIN;
|
return c.NSS_STATUS_TRYAGAIN;
|
||||||
},
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (cgroup) |got| {
|
||||||
|
gr.* = got;
|
||||||
|
return c.NSS_STATUS_SUCCESS;
|
||||||
|
} else {
|
||||||
|
errnop.* = @enumToInt(os.E.NOENT);
|
||||||
|
return c.NSS_STATUS_NOTFOUND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,27 +184,29 @@ export fn _nss_turbo_getgrnam_r(
|
|||||||
buflen: usize,
|
buflen: usize,
|
||||||
errnop: *c_int,
|
errnop: *c_int,
|
||||||
) c.enum_nss_status {
|
) c.enum_nss_status {
|
||||||
const db = getDb(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
const db = getDBErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
||||||
const nameSlice = mem.sliceTo(name, 0);
|
const nameSlice = mem.sliceTo(name, 0);
|
||||||
if (db.getgrnam(nameSlice, buffer[0..buflen])) |maybe_cgroup| {
|
var buf = buffer[0..buflen];
|
||||||
if (maybe_cgroup) |cgroup| {
|
var cgroup = db.getgrnam(nameSlice, buf) catch |err| switch (err) {
|
||||||
group.* = cgroup;
|
error.BufferTooSmall => {
|
||||||
|
errnop.* = @enumToInt(os.E.RANGE);
|
||||||
|
return c.NSS_STATUS_TRYAGAIN;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (cgroup) |got| {
|
||||||
|
group.* = got;
|
||||||
return c.NSS_STATUS_SUCCESS;
|
return c.NSS_STATUS_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
errnop.* = @enumToInt(os.E.NOENT);
|
errnop.* = @enumToInt(os.E.NOENT);
|
||||||
return c.NSS_STATUS_NOTFOUND;
|
return c.NSS_STATUS_NOTFOUND;
|
||||||
}
|
}
|
||||||
} else |err| switch (err) {
|
|
||||||
error.BufferTooSmall => {
|
|
||||||
errnop.* = @enumToInt(os.E.RANGE);
|
|
||||||
return c.NSS_STATUS_TRYAGAIN;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn _nss_turbo_setpwent(_: c_int) void {
|
export fn _nss_turbo_setpwent(_: c_int) void {
|
||||||
global_init.call();
|
global_init.call();
|
||||||
if (global_state) |*state| {
|
var state = global_state orelse return;
|
||||||
|
|
||||||
state.getpwent_iterator_mu.lock();
|
state.getpwent_iterator_mu.lock();
|
||||||
defer state.getpwent_iterator_mu.unlock();
|
defer state.getpwent_iterator_mu.unlock();
|
||||||
|
|
||||||
@ -213,7 +218,6 @@ export fn _nss_turbo_setpwent(_: c_int) void {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
export fn _nss_turbo_endpwent() void {
|
export fn _nss_turbo_endpwent() void {
|
||||||
global_init.call();
|
global_init.call();
|
||||||
@ -225,36 +229,75 @@ export fn _nss_turbo_endpwent() void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export fn _nss_turbo_setgrent(_: c_int) void {
|
export fn _nss_turbo_setgrent(_: c_int) void {
|
||||||
global_init.call();
|
var state = getState() orelse return;
|
||||||
if (global_state) |*state| {
|
|
||||||
state.getgrent_iterator_mu.lock();
|
state.getgrent_iterator_mu.lock();
|
||||||
defer state.getgrent_iterator_mu.unlock();
|
defer state.getgrent_iterator_mu.unlock();
|
||||||
|
|
||||||
state.getgrent_iterator = PackedGroup.iterator(
|
state.getgrent_iterator = PackedGroup.iterator(
|
||||||
state.file.db.groups,
|
state.file.db.groups,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
export fn _nss_turbo_endgrent() void {
|
export fn _nss_turbo_endgrent() void {
|
||||||
global_init.call();
|
var state = getState() orelse return;
|
||||||
if (global_state) |*state| {
|
|
||||||
state.getgrent_iterator_mu.lock();
|
state.getgrent_iterator_mu.lock();
|
||||||
defer state.getgrent_iterator_mu.unlock();
|
defer state.getgrent_iterator_mu.unlock();
|
||||||
state.getgrent_iterator = null;
|
state.getgrent_iterator = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export fn _nss_turbo_getgrent_r(
|
||||||
|
result: *CGroup,
|
||||||
|
buffer: [*]u8,
|
||||||
|
buflen: usize,
|
||||||
|
errnop: *c_int,
|
||||||
|
) c.enum_nss_status {
|
||||||
|
var state = getStateErrno(errnop) orelse return c.NSS_STATUS_UNAVAIL;
|
||||||
|
|
||||||
|
state.getgrent_iterator_mu.lock();
|
||||||
|
defer state.getgrent_iterator_mu.unlock();
|
||||||
|
|
||||||
|
var it = state.getgrent_iterator orelse {
|
||||||
|
// logic from _nss_systemd_getgrent_r
|
||||||
|
errnop.* = @enumToInt(os.E.HOSTDOWN);
|
||||||
|
return c.NSS_STATUS_UNAVAIL;
|
||||||
|
};
|
||||||
|
|
||||||
|
var group = it.next() orelse {
|
||||||
|
errnop.* = @enumToInt(os.E.NOENT);
|
||||||
|
return c.NSS_STATUS_NOTFOUND;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (state.file.db.getGroup(group, buffer[0..buflen])) |cgroup| {
|
||||||
|
result.* = cgroup;
|
||||||
|
return c.NSS_STATUS_SUCCESS;
|
||||||
|
} else |err| switch (err) {
|
||||||
|
error.BufferTooSmall => {
|
||||||
|
errnop.* = @enumToInt(os.E.RANGE);
|
||||||
|
return c.NSS_STATUS_TRYAGAIN;
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getDb(errnop: *c_int) ?DB {
|
fn getState() ?State {
|
||||||
|
global_init.call();
|
||||||
|
return global_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getStateErrno(errnop: *c_int) ?State {
|
||||||
global_init.call();
|
global_init.call();
|
||||||
if (global_state) |state| {
|
if (global_state) |state| {
|
||||||
return state.file.db;
|
return state;
|
||||||
} else {
|
} else {
|
||||||
errnop.* = @enumToInt(os.E.AGAIN);
|
errnop.* = @enumToInt(os.E.AGAIN);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn getDBErrno(errnop: *c_int) ?DB {
|
||||||
|
if (getStateErrno(errnop)) |state| {
|
||||||
|
return state.file.db;
|
||||||
|
} else return null;
|
||||||
|
}
|
||||||
|
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
|
|
||||||
test "getpwuid_r and getpwnam_r" {
|
test "getpwuid_r and getpwnam_r" {
|
||||||
|
Loading…
Reference in New Issue
Block a user