Something went wrong. Try again.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155const std = @import("std");
const cdl = @import("root.zig");
/// ownedpub fn hostname() ![]const u8 { var buf: [std.posix.HOST_NAME_MAX]u8 = undefined; const hostname_buf = try std.posix.gethostname(&buf); return try cdl.gpa.dupe(u8, hostname_buf);}
pub fn user() !?[]const u8 { const pwinfo = try PWInfo.get(); if (pwinfo) |pw| return pw.user;
if (cdl.environ_map) |envmap| return envmap.get("USER"); if (cdl.environ_map) |envmap| return envmap.get("LOGNAME");
return null;}
pub fn shell() !?[]const u8 { const shell_str = blk: { const pwinfo = try PWInfo.get(); if (pwinfo) |pw| break :blk pw.shell;
break :blk if (cdl.environ_map) |envmap| envmap.get("SHELL") else null; } orelse return null;
if (std.mem.cutScalarLast(u8, shell_str, '/')) |parts| return parts[1];
return shell_str;}
pub fn osname() !?[]const u8 { const f = try std.Io.Dir.openFileAbsolute(cdl.io, "/etc/os-release", .{});
var buf: [0x1000]u8 = undefined; var file_reader = f.reader(cdl.io, &buf); var reader = &file_reader.interface;
while (try reader.takeDelimiter('\n')) |line| if (std.mem.cutPrefix(u8, line, "NAME=")) |name| return try cdl.allocator.dupe(u8, trimquotes(name)); return null;}
pub fn desktop() ?[]const u8 { if (cdl.environ_map) |envmap| return envmap.get("XDG_CURRENT_DESKTOP"); return null;}
pub fn session() ?[]const u8 { if (cdl.environ_map) |envmap| return envmap.get("XDG_SESSION_TYPE"); return null;}
pub fn terminal() ?[]const u8 { if (cdl.environ_map) |envmap| return envmap.get("TERMINAL"); const nterm: ?[]const u8 = blk: { const termenv = if (cdl.environ_map) |envmap| envmap.get("TERM") else null; if (termenv) |term| if (term.len > 0) if (std.mem.findScalar(u8, term, '-')) |i| break :blk term[0..i] else break :blk term; break :blk null; }; if (nterm) |term| if (!std.mem.eql(u8, term, "xterm") and !std.mem.eql(u8, term, "linux")) return term;
return null;}
pub fn editor() ?[]const u8 { if (cdl.environ_map) |envmap| return envmap.get("EDITOR"); return null;}
const PWInfo = struct { user: ?[]const u8, shell: ?[]const u8, dir: ?[]const u8,
var cached: ?@This() = null;
pub fn get() !?PWInfo { if (PWInfo.cached) |c| return c;
const f = try std.Io.Dir.openFileAbsolute(cdl.io, "/etc/passwd", .{});
var buf: [0x1000]u8 = undefined; var file_reader = f.reader(cdl.io, &buf); var reader = &file_reader.interface;
const uid = std.os.linux.getuid(); w: while (try reader.takeDelimiter('\n')) |line| { var parts = std.mem.splitScalar(u8, line, ':'); var pw_user: ?[]const u8 = null; var pw_shell: ?[]const u8 = null; var pw_dir: ?[]const u8 = null;
var i: usize = 0; while (parts.next()) |part| : (i = i + 1) switch (i) { 0 => pw_user = part, 2 => if (try std.fmt.parseInt(u32, part, 10) != uid) continue :w, 5 => pw_dir = part, 6 => pw_shell = part, else => {}, };
return .{ .user = if (pw_user) |user_| try cdl.allocator.dupe(u8, user_) else null, .shell = if (pw_shell) |shell_| try cdl.allocator.dupe(u8, shell_) else null, .dir = if (pw_dir) |dir_| try cdl.allocator.dupe(u8, dir_) else null, }; }
return null; }};
// helpers ====================================================================
fn trimquotes(s: []const u8) []const u8 { if (s.len < 2) return s; const open = switch (s[0]) { '"' => s[0], '\'' => s[0], else => return s, }; // assume malformed if (s[s.len - 1] != open) return s[1..]; return s[1 .. s.len - 1];}
test "trim quotes" { try std.testing.expectEqualStrings("meow", trimquotes("meow")); try std.testing.expectEqualStrings("meow", trimquotes( \\"meow" )); try std.testing.expectEqualStrings("meow", trimquotes( \\'meow' )); try std.testing.expectEqualStrings("meow", trimquotes( \\'meow )); try std.testing.expectEqualStrings("meow", trimquotes( \\"meow ));}