const std = @import("std"); const ArgError = error{ NotEnoughArgs, BadDomain, InvalidAddressVer, }; pub const IP_VER_ENUM = enum(u3) { Both = 0, IPv4 = 4, IPv6 = 6, }; pub const IPs = struct { v4: [:0]const u8, v6: [:0]const u8, }; pub const Domain = struct { name: [:0]const u8, labels: u4, }; pub fn check_perms() !void { var f = try std.fs.openFileAbsolute("/etc/hosts", .{ .mode = .write_only }); f.close(); } pub fn get_input() !struct { Domain, IP_VER_ENUM, } { var args = std.process.args(); _ = args.next(); // consume calling binary arg const domain_str = args.next() orelse return ArgError.NotEnoughArgs; const domain = try check_domain(domain_str); const ip_ver_str = args.next() orelse return ArgError.NotEnoughArgs; const ip_ver = std.meta.intToEnum(IP_VER_ENUM, try std.fmt.parseInt(u3, ip_ver_str, 10)) catch return ArgError.InvalidAddressVer; return .{ domain, ip_ver }; } fn check_domain(domain_str: [:0]const u8) !Domain { var domain = Domain{ .name = domain_str, .labels = 0, }; var labels = std.mem.split(u8, domain_str, "."); var last: []const u8 = ""; while (labels.next()) |segment| { last = segment; domain.labels += 1; } if (domain.labels <= 1 or !std.mem.eql(u8, last, "local")) { return ArgError.BadDomain; } return domain; }