const std = @import("std"); const os = std.os; const fmt = std.fmt; const mem = std.mem; const DB = @import("DB.zig"); const File = @import("File.zig"); const CGroup = @import("Group.zig").CGroup; const PackedGroup = @import("PackedGroup.zig"); const CUser = @import("User.zig").CUser; const PackedUser = @import("PackedUser.zig"); const c = @cImport({ @cInclude("stdlib.h"); @cInclude("nss.h"); }); export const turbonss_default_path: [:0]const u8 = "/etc/turbonss/db.turbo"; // State is a type of the global variable holding the process state: // the DB handle and all the iterators. const State = struct { file: ?File, getpwent_iterator: ?PackedUser.Iterator, getgrent_iterator: ?PackedGroup.Iterator, omit_members: bool, err_msg: [1024]u8, }; // state is initialized on library startup. var state: State = undefined; // constructor export fn _turbo_init() void { const fname = os.getenvZ("TURBONSS_DB") orelse turbonss_default_path[0..]; state.file = File.open(fname) catch |err| { _ = fmt.bufPrint(&state.err_msg, "open {s}: {s}", .{ fname, @errorName(err) }) catch return; return; }; const omit_members_env = os.getenvZ("TURBONSS_OMIT_MEMBERS") orelse "auto"; state.omit_members = shouldOmitMembers(omit_members_env, os.argv); return; } fn shouldOmitMembers(env: []const u8, argv: [][*:0]u8) bool { if (mem.eql(u8, env, "1")) return true; if (mem.eql(u8, env, "0")) return false; if (argv.len == 0) return false; return mem.eql(u8, mem.sliceTo(argv[0], 0), "id"); } // destructor export fn _turbo_fini() void { if (state.file) |*fooo| fooo.close(); } export fn _nss_turbo_getpwuid_r( uid: c_uint, res: *CUser, buf: [*]u8, len: usize, errnop: *c_int, ) c.enum_nss_status { _ = uid; _ = res; _ = buf; _ = len; _ = errnop; return 0; }