Add env var args, old values purging

This commit is contained in:
Muaz Ahmad 2024-05-12 18:52:13 +05:00
parent 6d8710545e
commit 93045d80f7
4 changed files with 65 additions and 14 deletions

View file

@ -1,19 +1,25 @@
const std = @import("std"); const std = @import("std");
const util = @import("util.zig"); const util = @import("util.zig");
const hosts_header = "# local-etc-hosts-updater";
pub fn update_hosts(ip: util.IP) !void { pub fn update_hosts(ip: util.IP) !void {
try create_tmp_hosts(ip); try create_tmp_hosts(ip);
try move_tmp_hosts(); try move_tmp_hosts();
} }
fn create_tmp_hosts(ip: util.IP) !void { inline fn check_purge(line: []u8, purging: *bool, skip_last_line: *bool) void {
_ = ip; if (purging.* and std.mem.eql(u8, line, "")) {
purging.* = false;
skip_last_line.* = true;
}
var old_hosts = try std.fs.openFileAbsolute("/etc/hosts", .{ .mode = .read_only }); if (std.mem.eql(u8, line, hosts_header)) {
defer old_hosts.close(); purging.* = true;
var tmp_hosts = try std.fs.createFileAbsolute("/tmp/hosts", .{ .truncate = true }); }
defer tmp_hosts.close(); }
fn purge_existing(old_hosts: std.fs.File, tmp_hosts: std.fs.File) !void {
var buff = [_]u8{0x00} ** 50; var buff = [_]u8{0x00} ** 50;
var buff_stream = std.io.fixedBufferStream(&buff); var buff_stream = std.io.fixedBufferStream(&buff);
const buff_reader = buff_stream.reader(); const buff_reader = buff_stream.reader();
@ -21,18 +27,58 @@ fn create_tmp_hosts(ip: util.IP) !void {
var old_reader = old_hosts.reader(); var old_reader = old_hosts.reader();
const tmp_writer = tmp_hosts.writer(); const tmp_writer = tmp_hosts.writer();
var purging = false;
var skip_last_line = false;
while (old_reader.streamUntilDelimiter(buff_writer, '\n', 50 - 1)) |_| { while (old_reader.streamUntilDelimiter(buff_writer, '\n', 50 - 1)) |_| {
defer buff_stream.pos = 0;
var n = buff_stream.pos; var n = buff_stream.pos;
// do things to line // do things to line
check_purge(buff[0..n], &purging, &skip_last_line);
if (purging) {
continue;
}
if (skip_last_line) {
skip_last_line = false;
continue;
}
// copy line
buff[n] = '\n'; buff[n] = '\n';
n += 1; n += 1;
buff_stream.pos = 0; buff_stream.pos = 0;
try buff_reader.streamUntilDelimiter(tmp_writer, '\n', 50); try buff_reader.streamUntilDelimiter(tmp_writer, '\n', 50);
try tmp_writer.writeByte('\n'); try tmp_writer.writeByte('\n');
buff_stream.pos = 0; } else |err| {
} else |_| { if (err != error.EndOfStream) {
// EOF return err;
}
}
}
fn append_new(tmp_hosts: std.fs.File, addr: std.net.Address) !void {
_ = addr;
const writer = tmp_hosts.writer();
var buff = [_]u8{0x00} ** 50;
const header_len = hosts_header.*.len;
@memcpy(buff[0..header_len], hosts_header);
try writer.writeAll(buff[0..header_len]);
try writer.writeByte('\n');
try writer.writeByte('\n');
}
fn create_tmp_hosts(ip: util.IP) !void {
var old_hosts = try std.fs.openFileAbsoluteZ(try util.getenv("OLD_HOSTS_PATH"), .{ .mode = .read_only });
defer old_hosts.close();
var tmp_hosts = try std.fs.createFileAbsoluteZ(try util.getenv("TMP_HOSTS_PATH"), .{ .truncate = true });
defer tmp_hosts.close();
try purge_existing(old_hosts, tmp_hosts);
if (ip) |addr| {
try append_new(tmp_hosts, addr);
} }
} }

View file

@ -5,7 +5,7 @@ const hosts = @import("hosts.zig");
pub fn main() !void { pub fn main() !void {
try util.check_perms(); try util.check_perms();
const domain, const ip_ver = try util.get_input(); const domain, const ip_info = try util.get_input();
const ip = try mdns.get_mdns(domain, ip_ver); const ip = try mdns.get_mdns(domain, ip_info);
try hosts.update_hosts(ip); try hosts.update_hosts(ip);
} }

View file

@ -165,5 +165,5 @@ fn parse_mdns_response(response: []u8, ip_info: util.IPInfo) !util.IP {
} }
} }
} }
return addr orelse MDNSError.NoMatchingAddress; return addr;
} }

View file

@ -6,6 +6,7 @@ const ArgError = error{
InvalidAddressVer, InvalidAddressVer,
InterfaceRequired, InterfaceRequired,
InvalidInterface, InvalidInterface,
EnvVarNotSet,
}; };
pub const IP_VER_ENUM = enum(u3) { pub const IP_VER_ENUM = enum(u3) {
@ -13,7 +14,7 @@ pub const IP_VER_ENUM = enum(u3) {
IPv6 = 6, IPv6 = 6,
}; };
pub const IP = std.net.Address; pub const IP = ?std.net.Address;
pub const IPInfo = struct { pub const IPInfo = struct {
version: IP_VER_ENUM, version: IP_VER_ENUM,
@ -25,8 +26,12 @@ pub const Domain = struct {
labels: [5][]const u8, labels: [5][]const u8,
}; };
pub fn getenv(key: [*:0]const u8) ![*:0]const u8 {
return (std.c.getenv(key) orelse ArgError.EnvVarNotSet);
}
pub fn check_perms() !void { pub fn check_perms() !void {
var f = try std.fs.openFileAbsolute("/etc/hosts", .{ .mode = .write_only }); var f = try std.fs.openFileAbsoluteZ(try getenv("OLD_HOSTS_PATH"), .{ .mode = .write_only });
f.close(); f.close();
} }