Add env var args, old values purging
This commit is contained in:
parent
6d8710545e
commit
93045d80f7
4 changed files with 65 additions and 14 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,5 +165,5 @@ fn parse_mdns_response(response: []u8, ip_info: util.IPInfo) !util.IP {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return addr orelse MDNSError.NoMatchingAddress;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue