~gpanders/iboot

d7d8c4708a579af616125a6d9499212234cb073a — Greg Anders 12 days ago 9d2c674
Add zig implementation
4 files changed, 81 insertions(+), 4 deletions(-)

M .gitignore
M Makefile
M iboot.c
A iboot.zig
M .gitignore => .gitignore +1 -0
@@ 1,2 1,3 @@
config.h
iboot
zig-cache

M Makefile => Makefile +10 -3
@@ 1,13 1,20 @@
PREFIX := /usr/local
ZFLAGS := -I. --release-small --strip --single-threaded
CFLAGS := -Wall -Wpedantic -Os -std=c99
SRC := $(if $(ZIG),iboot.zig,iboot.c)

iboot: iboot.c config.h
iboot: $(SRC) config.h
ifneq ($(ZIG),)
	zig build-exe $(ZFLAGS) --name $@ $<
else
	$(CC) $(CFLAGS) -o $@ $<
endif

config.h: config.def.h
	cp $< $@

install:
	install -m 0755 iboot /usr/local/bin/
	install -m 0755 iboot $(PREFIX)/bin/

clean:
	rm -rf iboot
	rm -rf iboot iboot.o

M iboot.c => iboot.c +1 -1
@@ 50,7 50,7 @@ int create_socket()
void send_command(int sockfd, enum action action)
{
	char buf[BUF_SIZE];
	sprintf(buf, "%s%c\r", PASSWORD, action);
	sprintf(buf, "\x1b%s\x1b%c\r", PASSWORD, action);
	if (write(sockfd, buf, BUF_SIZE) != BUF_SIZE) {
		fprintf(stderr, "partial/failed write\n");
		exit(EXIT_FAILURE);

A iboot.zig => iboot.zig +69 -0
@@ 0,0 1,69 @@
const std = @import("std");
const fmt = std.fmt;
const mem = std.mem;
const net = std.net;

const config = @cImport(@cInclude("config.h"));

const Action = enum(u8) {
    ON = 'n',
    OFF = 'f',
    CYCLE = 'c',
    QUERY = 'q',

    fn parse(str: []const u8) !Action {
        if (mem.eql(u8, str, "on")) {
            return .ON;
        }

        if (mem.eql(u8, str, "off")) {
            return .OFF;
        }

        if (mem.eql(u8, str, "cycle")) {
            return .CYCLE;
        }

        if (mem.eql(u8, str, "query")) {
            return .QUERY;
        }

        return error.InvalidAction;
    }
};

inline fn usage() noreturn {
    std.debug.warn("Usage: iboot <on|off|cycle|query>\n", .{});
    std.process.exit(1);
}

pub fn main() anyerror!void {
    var args = std.process.args();
    _ = args.skip();

    const action = if (args.nextPosix()) |arg|
        Action.parse(arg) catch {
            std.debug.warn("Invalid action: {}\n", .{arg});
            usage();
        }
    else
        usage();

    const addr = try net.Address.parseIp4(mem.span(config.ADDRESS), config.PORT);
    const sock = try net.tcpConnectToAddress(addr);

    // 4 extra bytes for the two escape characters, the action character, and
    // the carriage return
    comptime var size = mem.span(config.PASSWORD).len + 4;
    var buf: [size]u8 = undefined;
    _ = try fmt.bufPrint(&buf, "\x1b{}\x1b{c}\r", .{
        mem.span(config.PASSWORD),
        @enumToInt(action),
    });

    try sock.writeAll(&buf);
    mem.set(u8, &buf, 0);
    _ = try sock.read(&buf);

    std.debug.warn("{}\n", .{buf});
}