From cd99ad5e4e436972421e196b1787f1fa8596768b Mon Sep 17 00:00:00 2001 From: Kalle Carlbark Date: Mon, 23 Sep 2024 21:46:15 +0200 Subject: [PATCH] wip: gw and dns --- src/macos.zig | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ src/main.zig | 30 ++++++++++++++++++-- src/namnsdag.zig | 49 ++++++++++++++++++++++++++++++++ src/sys.zig | 21 ++++++++++++++ 4 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 src/namnsdag.zig diff --git a/src/macos.zig b/src/macos.zig index dd5253f..0bb4883 100644 --- a/src/macos.zig +++ b/src/macos.zig @@ -115,6 +115,78 @@ pub fn get_vpn_info() !void { // Convert CFStringRef to C string (null-terminated) } +pub fn get_dns_servers(allocator: std.mem.Allocator) ![]const u8 { + const store: c.SCDynamicStoreRef = c.SCDynamicStoreCreate(null, CFStringCreateWithCStringZig("GetDNS"), null, null); + + if (store == null) { + return error.CreateDynamicStoreRef; + } + + const dnsDict: c.CFDictionaryRef = @ptrCast(c.SCDynamicStoreCopyValue(store, CFStringCreateWithCStringZig("State:/Network/Global/DNS"))); + + const servers: c.CFArrayRef = @ptrCast(c.CFDictionaryGetValue(dnsDict, c.kSCPropNetDNSServerAddresses)); + + if (servers == null) { + return error.NoDNSServersFound; + } + + const count: c.CFIndex = c.CFArrayGetCount(servers); + + if (count < 1) { + return try std.fmt.allocPrint(allocator, "no found\n", .{}); + } + + var arena = std.heap.ArenaAllocator.init(allocator); + defer arena.deinit(); + + var server_list = std.ArrayList(u8).init(arena.allocator()); + + for (0..@intCast(count)) |i| { + const server: c.CFStringRef = @ptrCast(c.CFArrayGetValueAtIndex(servers, @intCast(i))); + + if (server != null) { + var server_buf: [256]u8 = undefined; + if (c.CFStringGetCString(server, &server_buf[0], server_buf.len, c.kCFStringEncodingUTF8) == 1) { + const zig_string = std.mem.sliceTo(server_buf[0..], 0); + + try server_list.appendSlice(zig_string); + if (i < (count - 1)) { + try server_list.append(','); + } + } + } + } + c.CFRelease(dnsDict); + c.CFRelease(store); + + return try std.fmt.allocPrint(allocator, ": {s}\n", .{server_list.items}); +} + +pub fn get_default_gateway(buf: []u8) ![]const u8 { + const store: c.SCDynamicStoreRef = c.SCDynamicStoreCreate(null, CFStringCreateWithCStringZig("GetGateway"), null, null); + defer c.CFRelease(store); + + if (store == null) { + return error.CreateDynamicStoreRef; + } + + const ip4: c.CFDictionaryRef = @ptrCast(c.SCDynamicStoreCopyValue(store, CFStringCreateWithCStringZig("State:/Network/Global/IPv4"))); + defer c.CFRelease(ip4); + + const gw: c.CFStringRef = @ptrCast(c.CFDictionaryGetValue(ip4, CFStringCreateWithCStringZig("Router"))); + + if (gw == null) { + return try std.fmt.bufPrint(buf, ": unknown\n", .{}); + } + + var gw_buf: [256]u8 = undefined; + if (c.CFStringGetCString(gw, &gw_buf[0], gw_buf.len, c.kCFStringEncodingUTF8) == 1) { + return try std.fmt.bufPrint(buf, ": {s}\n", .{std.mem.sliceTo(gw_buf[0..], 0)}); + } + + return try std.fmt.bufPrint(buf, ": unknown\n", .{}); +} + pub fn get_battery_info(buf: []u8) ![]const u8 { const power_sources_info: c.CFTypeRef = c.IOPSCopyPowerSourcesInfo(); diff --git a/src/main.zig b/src/main.zig index 3522151..4277dda 100644 --- a/src/main.zig +++ b/src/main.zig @@ -35,6 +35,12 @@ pub fn main() !void { vx.caps.unicode = .unicode; vx.caps.kitty_graphics = true; + const dns_servers = try sys.get_dns_servers(allocator); + defer allocator.free(dns_servers.text); + + var gw_buf: [64]u8 = undefined; + const default_gateway = try sys.get_default_gateway(&gw_buf); + var term_buf: [64]u8 = undefined; const current_terminal = try sys.get_terminal(&term_buf); @@ -99,7 +105,7 @@ pub fn main() !void { .y_off = 1, .x_off = dims.cols + 1, .width = .{ .limit = 40 }, - .height = .{ .limit = 16 }, + .height = .{ .limit = 18 }, .border = .{ .where = .{ .other = border_locations, @@ -221,6 +227,26 @@ pub fn main() !void { }, }, battery, + .{ + .text = " Default GW", + .style = .{ + .fg = .{ + .index = 7, + }, + .bold = true, + }, + }, + default_gateway, + .{ + .text = " DNS servers", + .style = .{ + .fg = .{ + .index = 7, + }, + .bold = true, + }, + }, + dns_servers, .{ .text = " ▂▂▂", .style = .{ @@ -355,7 +381,7 @@ pub fn main() !void { }; try image.draw(logo_win, .{}); result = try whoami_win.print(&whoami_info, .{ .wrap = .word }); - result = try info_win.print(&system_info, .{ .wrap = .word }); + result = try info_win.print(&system_info, .{ .wrap = .grapheme }); try vx.prettyPrint(tty.anyWriter()); try buf_writer.flush(); } diff --git a/src/namnsdag.zig b/src/namnsdag.zig new file mode 100644 index 0000000..cb1d173 --- /dev/null +++ b/src/namnsdag.zig @@ -0,0 +1,49 @@ +const std = @import("std"); + +const namnsdag_url = "https://sholiday.faboul.se/dagar/v2.1"; + +const Day = struct { + date: []const u8, + weekday: []const u8, + work_free_day: []const u8, + red_day: []const u8, + week: []const u8, + day_in_week: []const u8, + weekend: []const u8, + flag_day: []const u8, + sequeeze_day: []const u8, + eve: []const u8, + day_before_weekday: []const u8, + name: []const u8, +}; + +const Days = struct { + cache_time: []const u8, + version: []const u8, + uri: []const u8, + start_date: []const u8, + end_date: []const u8, + days: []Day, +}; + +pub fn client(allocator: std.mem.Allocator) []const u8 { + var http_client = std.http.Client{ .allocator = allocator }; + defer http_client.deinit(); + + const uri = try std.Uri.parse(namnsdag_url); + var buf: [4096]u8 = undefined; + + const headers = std.http.Client.Request.Headers{ + .content_type = std.http.Client.Request.Headers.Value{ + .override = "application/json", + }, + }; + + var req = try http_client.open(.GET, uri, .{ .server_header_buffer = &buf, .headers = headers }); + + try req.send(); + + try req.finish(); + + try req.wait(); +} diff --git a/src/sys.zig b/src/sys.zig index 4230b8a..775241c 100644 --- a/src/sys.zig +++ b/src/sys.zig @@ -17,6 +17,27 @@ const Shell = struct { version: []const u8, }; +pub fn get_dns_servers(allocator: std.mem.Allocator) !vaxis.Cell.Segment { + switch (builtin.os.tag) { + .macos => { + return .{ + .text = try macos.get_dns_servers(allocator), + }; + }, + else => return .{ .text = try std.fmt.allocPrint(allocator, ": unknown", .{}) }, + } +} + +pub fn get_default_gateway(buf: []u8) !vaxis.Cell.Segment { + switch (builtin.os.tag) { + .macos => { + return .{ + .text = try macos.get_default_gateway(buf), + }; + }, + else => return .{ .text = try std.fmt.bufPrint(buf, ": unknown", .{}) }, + } +} pub fn get_shell(allocator: std.mem.Allocator) !vaxis.Cell.Segment { const shell_env = std.posix.getenv("SHELL") orelse "Unknown"; var shell_path = std.mem.splitBackwards(u8, shell_env, "/");