121 lines
2.9 KiB
Zig
121 lines
2.9 KiB
Zig
const std = @import("std");
|
|
const os = std.os;
|
|
|
|
const c = @cImport({
|
|
@cInclude("stdio.h");
|
|
@cInclude("stdlib.h");
|
|
@cInclude("sys/stat.h");
|
|
@cInclude("string.h");
|
|
@cInclude("time.h");
|
|
});
|
|
|
|
const warn = std.debug.warn;
|
|
const allocator = std.heap.c_allocator;
|
|
|
|
fn sliceify(ptr: [*]u8) []u8 {
|
|
return ptr[0..c.strlen(ptr)];
|
|
}
|
|
|
|
fn sliceifyKnown(slice: []u8) []u8 {
|
|
return slice[0..c.strlen(slice.ptr)];
|
|
}
|
|
|
|
export fn journal_open(topic_cptr: ?[*]u8) os.fd_t {
|
|
const topic = sliceify(topic_cptr.?);
|
|
|
|
const journal_dir = std.fs.path.resolve(allocator, [_][]const u8{
|
|
std.os.getenvC(c"HOME").?,
|
|
".lunabot",
|
|
}) catch |err| {
|
|
warn("failed to resolve paths: {}\n", err);
|
|
return -1;
|
|
};
|
|
|
|
warn("journal_dir = {}\n", journal_dir);
|
|
|
|
std.fs.makeDir(journal_dir) catch |err| {
|
|
if (err != error.PathAlreadyExists) {
|
|
warn("failed to create journal dir {}: {}\n", journal_dir, err);
|
|
return -1;
|
|
}
|
|
};
|
|
|
|
const journal_path = std.fmt.allocPrint(allocator, "{}/{}", journal_dir, topic) catch |err| {
|
|
warn("failed to allocprint journal path: {}\n", err);
|
|
return -1;
|
|
};
|
|
defer allocator.free(journal_path);
|
|
|
|
warn("journal_path = {}\n", journal_path);
|
|
|
|
const fd = std.os.open(
|
|
journal_path,
|
|
std.os.O_WRONLY | std.os.O_CREAT | std.os.O_APPEND,
|
|
0o755,
|
|
) catch |err| {
|
|
warn("failed to open {}: {}\n", journal_path, err);
|
|
return -1;
|
|
};
|
|
|
|
return fd;
|
|
}
|
|
|
|
export fn journal_write(journal: os.fd_t, message_cptr: ?[*]u8) void {
|
|
std.os.write(
|
|
journal,
|
|
sliceify(message_cptr.?),
|
|
) catch |err| {
|
|
std.debug.warn("Error while writing to file: {}\n", err);
|
|
return;
|
|
};
|
|
}
|
|
|
|
export fn journal_close(journal: os.fd_t) void {
|
|
std.os.close(journal);
|
|
}
|
|
|
|
export fn journal_write_topic(
|
|
journal: os.fd_t,
|
|
topic_cptr: ?[*]u8,
|
|
message_cptr: ?[*]u8,
|
|
) void {
|
|
warn("zig uwu\n");
|
|
var topic = sliceify(topic_cptr.?);
|
|
var message = sliceify(message_cptr.?);
|
|
|
|
var tstamp_total = allocator.alloc(u8, 128) catch |err| {
|
|
warn("failed to allocate string for timestamp\n");
|
|
return;
|
|
};
|
|
defer allocator.free(tstamp_total);
|
|
|
|
var rawtime: c.time_t = undefined;
|
|
|
|
_ = c.time(&rawtime);
|
|
var cur_time: [*c]const c.struct_tm = c.gmtime(&rawtime);
|
|
_ = c.strftime(tstamp_total.ptr, usize(128), c"%c", cur_time);
|
|
|
|
var tstamp = sliceifyKnown(tstamp_total);
|
|
|
|
std.debug.warn("tstamp: {}\ntopic: {}\nmsg: {}\n", tstamp, topic, message);
|
|
|
|
var fmt_msg = std.fmt.allocPrint(
|
|
allocator,
|
|
"[{}] [{}]: {}\n",
|
|
tstamp,
|
|
topic,
|
|
message,
|
|
) catch |err| {
|
|
warn("Failed to make formatted message: {}\n", err);
|
|
return;
|
|
};
|
|
|
|
// catch unreachable is intended.
|
|
var fmt_msg_cstr = std.cstr.addNullByte(
|
|
allocator,
|
|
fmt_msg,
|
|
) catch unreachable;
|
|
|
|
journal_write(journal, fmt_msg_cstr.ptr);
|
|
}
|