Compare commits
6 Commits
9846c7ad27
...
5ca407f1d8
Author | SHA1 | Date | |
---|---|---|---|
5ca407f1d8 | |||
6d8d0d8c2d | |||
24cb04160a | |||
adbaf11d71 | |||
db13c085c8 | |||
591f58d70a |
@ -1050,6 +1050,50 @@ pre { /* DRY who? */
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/blah/2025-04-01.html
|
||||||
|
|
||||||
|
: openbsd server
|
||||||
|
|
||||||
|
i'm using caddy instead of relayd,httpd,acme because i like an easy config for
|
||||||
|
web shit and i loathe tls stuff
|
||||||
|
|
||||||
|
/etc/caddy/Caddyfile
|
||||||
|
|
|
||||||
|
| # lightly modified default
|
||||||
|
| {
|
||||||
|
| http_port 8080
|
||||||
|
| https_port 8443
|
||||||
|
| admin unix//var/caddy/admin.sock|0220
|
||||||
|
| }
|
||||||
|
|
|
||||||
|
| trinity.moe {
|
||||||
|
| root * /srv/trinity.moe
|
||||||
|
| file_server
|
||||||
|
| }
|
||||||
|
|
|
||||||
|
| www.trinity.moe {
|
||||||
|
| redir https://trinity.moe{uri}
|
||||||
|
| }
|
||||||
|
|
||||||
|
cool and all, right? except caddy can't bind to low ports on openbsd, because
|
||||||
|
caddy isn't running as root (which is a security issue) and openbsd can't let
|
||||||
|
non-root processes bind to low ports like linux can. so we've bound to high
|
||||||
|
ports. let's fix this in pf(4)
|
||||||
|
|
||||||
|
/etc/pf.conf
|
||||||
|
| # [ defaults included, but i'm not copying them over here ]
|
||||||
|
| pass in on any proto tcp from any to any port 80 rdr-to 127.0.0.1 port 8080
|
||||||
|
| pass in on any proto tcp from any to any port 443 rdr-to 127.0.0.1 port 8443
|
||||||
|
|
||||||
|
okay cool
|
||||||
|
|
||||||
|
for a while trinity.moe was hosted on the same machine as feeling.murderu.us,
|
||||||
|
as of today that is no longer the case (i still own murderu.us and everything,
|
||||||
|
i just wanted a personal vps for other things too)
|
||||||
|
|
||||||
|
maybe there will be more blah posts but probably not
|
||||||
|
|
||||||
|
|
||||||
/blah/2024-12-01.html
|
/blah/2024-12-01.html
|
||||||
|
|
||||||
: vaporware i looked forward to
|
: vaporware i looked forward to
|
||||||
|
4
status/.gitignore
vendored
Normal file
4
status/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
*.o
|
||||||
|
order.c
|
||||||
|
settings.c
|
||||||
|
status
|
28
status/Makefile
Normal file
28
status/Makefile
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
CFLAGS += -g
|
||||||
|
|
||||||
|
.PHONY: run
|
||||||
|
run: status
|
||||||
|
./status
|
||||||
|
|
||||||
|
.PHONY: cleanall
|
||||||
|
cleanall: clean
|
||||||
|
rm -f order.c settings.c
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -f status *.o
|
||||||
|
|
||||||
|
status: status.c order.c libio.o libkeyval.o
|
||||||
|
time $(CC) $(CFLAGS) -o $@ $@.c libio.o libkeyval.o
|
||||||
|
|
||||||
|
order.c: order.def.c
|
||||||
|
- cp -v order.def.c $@
|
||||||
|
|
||||||
|
libio.o: libio.c libio.h
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ libio.c
|
||||||
|
|
||||||
|
libkeyval.o: libkeyval.c libkeyval.h settings.c
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ libkeyval.c
|
||||||
|
|
||||||
|
settings.c: settings.def.c
|
||||||
|
- cp -v settings.def.c $@
|
13
status/README
Normal file
13
status/README
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
__ ___ __ ___ _ _ __
|
||||||
|
/ _// // // // // // _/ STATUS
|
||||||
|
_'. / // _ // / / // /_'. how's your day going?
|
||||||
|
/__/ /_//_//_//_/ /__/ /__/ 2025 DTB. Public Domain.
|
||||||
|
|
||||||
|
build: $ make
|
||||||
|
|
||||||
|
libio.c, libio.h: libio, a wrapper around I/O functions for status(1)
|
||||||
|
libkeyval.c, libkeyval.h: libkeyval, a key/value system for status(1)
|
||||||
|
*.def.c: the default for foo.c, a configuration file #included
|
||||||
|
directly in a source-file
|
||||||
|
mod_*.c: modules to be #included directly in status.h
|
||||||
|
status.c: main() and boilerplate
|
19
status/libio.c
Normal file
19
status/libio.c
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* 2025 DTB. Public Domain. */
|
||||||
|
#undef NDEBUG /* LOAD-BEARING ASSERTS! */
|
||||||
|
#include <assert.h> /* assert(3) */
|
||||||
|
#include <errno.h> /* errno */
|
||||||
|
#include <stdio.h> /* fputs(3), stdout, NULL */
|
||||||
|
#include "libio.h"
|
||||||
|
|
||||||
|
/* output */
|
||||||
|
static char *hold = NULL;
|
||||||
|
|
||||||
|
void
|
||||||
|
drop(void) { hold = NULL; }
|
||||||
|
|
||||||
|
void
|
||||||
|
out(char *s) {
|
||||||
|
if (hold != NULL)
|
||||||
|
{ errno = 0; fputs(hold, stdout); assert(errno == 0); }
|
||||||
|
hold = s;
|
||||||
|
}
|
8
status/libio.h
Normal file
8
status/libio.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/* 2025 DTB. Public Domain. */
|
||||||
|
|
||||||
|
/* libio is a microscopic library that exists to separate less relevant code
|
||||||
|
* from status(1). It should not be used in critical applications for lack of
|
||||||
|
* recoverability (as opposed to <stdio.h> on its own). */
|
||||||
|
|
||||||
|
void drop(void); /* Set the buffer to NULL. */
|
||||||
|
void out(char *s); /* Print the buffer if not NULL and replace it with s. */
|
68
status/libkeyval.c
Normal file
68
status/libkeyval.c
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/* 2025 DTB. Public domain. */
|
||||||
|
|
||||||
|
#undef NDEBUG /* LOAD-BEARING ASSERTS! */
|
||||||
|
#include <assert.h> /* assert(3) */
|
||||||
|
#include <stdlib.h> /* atoi(3) */
|
||||||
|
#include <string.h> /* strcmp(3) */
|
||||||
|
#include "libkeyval.h"
|
||||||
|
|
||||||
|
static struct State state = { 0 };
|
||||||
|
|
||||||
|
void
|
||||||
|
cpy(char *key) {
|
||||||
|
state.settings[state.setting_last].key = key;
|
||||||
|
state.settings[state.setting_last].val = get(key);
|
||||||
|
assert(++state.setting_last < state_settings_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
del(char *key) {
|
||||||
|
size_t i;
|
||||||
|
for (i = idx(key); i < state.setting_last; ++i) {
|
||||||
|
state.settings[i].key = state.settings[i + 1].key;
|
||||||
|
state.settings[i].val = state.settings[i + 1].val;
|
||||||
|
}
|
||||||
|
--state.setting_last;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
get(char *key) { return state.settings[idx(key)].val; }
|
||||||
|
|
||||||
|
int
|
||||||
|
getd(char *key) { return atoi(get(key)); }
|
||||||
|
|
||||||
|
size_t
|
||||||
|
idx(char *key) {
|
||||||
|
size_t r;
|
||||||
|
for (r = 0; state.settings[r].key != NULL
|
||||||
|
&& strcmp(state.settings[r].key, key) != 0;
|
||||||
|
++r);
|
||||||
|
return (state.settings[r].key == NULL) ? state.setting_last : r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
keyval_init(void) {
|
||||||
|
/* Unnecessary, but means a wrong state.setting_last won't blow up. */
|
||||||
|
(void)memset(&state.settings[state.setting_last],
|
||||||
|
state_settings_size - state.setting_last, '\0');
|
||||||
|
#include "settings.c"
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
ren(char *key, char *new) {
|
||||||
|
size_t i;
|
||||||
|
if ((i = idx(key)) != state.setting_last)
|
||||||
|
{ state.settings[i].key = new; }
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
set(char *key, char *val) {
|
||||||
|
size_t i;
|
||||||
|
i = idx(key);
|
||||||
|
state.settings[i].key = key;
|
||||||
|
state.settings[i].val = val;
|
||||||
|
if (i == state.setting_last)
|
||||||
|
{ assert(++state.setting_last < state_settings_size); }
|
||||||
|
return i;
|
||||||
|
}
|
29
status/libkeyval.h
Normal file
29
status/libkeyval.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* 2025 DTB. Public domain. */
|
||||||
|
|
||||||
|
/* libkeyval is a key/value store library to be used for nonessential
|
||||||
|
* applications due to lack of recoverability (errors fail assert(3)).
|
||||||
|
* libkeyval deals with pointers and pointers only, and an effort has been made
|
||||||
|
* to reflect the simplicity of the procedure in the code itself. */
|
||||||
|
|
||||||
|
/* keyval store */
|
||||||
|
#ifndef state_settings_size
|
||||||
|
# define state_settings_size 100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct State {
|
||||||
|
size_t setting_last;
|
||||||
|
struct Setting { char *key; char *val; } settings[state_settings_size];
|
||||||
|
};
|
||||||
|
|
||||||
|
void cpy(char *key); /* Duplicate the setting key. */
|
||||||
|
void del(char *key); /* Delete the first instance of key in settings. */
|
||||||
|
char * get(char *key); /* Get the corresponding val to key in settings. */
|
||||||
|
int getd(char *key); /* get() that returns a decimal number if key was a
|
||||||
|
* number, or 0. */
|
||||||
|
void keyval_init(void); /* Sanitize the settings store. */
|
||||||
|
size_t idx(char *key); /* Returns the index of key if in settings, or
|
||||||
|
* state.setting_last. */
|
||||||
|
size_t ren(char *key, char *dst); /* Rename the first instance of key in
|
||||||
|
* settings. */
|
||||||
|
size_t set(char *key, char *val); /* Set the first instance of key in
|
||||||
|
* settings. */
|
5
status/mod_static.c
Normal file
5
status/mod_static.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
// #include "io.h" /* out(3) */
|
||||||
|
// #include "keyval.h" /* get(3) */
|
||||||
|
|
||||||
|
void
|
||||||
|
mod_static(char *s) { out(s); out(get("separator")); }
|
35
status/mod_time.c
Normal file
35
status/mod_time.c
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* 2025 DTB. Public Domain. */
|
||||||
|
// #undef NDEBUG /* LOAD BEARING ASSERTS */
|
||||||
|
// #include <assert.h> /* assert(3) */
|
||||||
|
// #include <stdlib.h> /* setenv(3), unsetenv(3), NULL */
|
||||||
|
// #include <time.h> /* localtime(3), strftime(3), time(2), tzset(3), time_t,
|
||||||
|
// * struct tm */
|
||||||
|
// #include "io.h" /* out(3) */
|
||||||
|
// #include "keyval.h" /* get(3) */
|
||||||
|
#ifndef mod_time_bufsize
|
||||||
|
# define mod_time_bufsize 100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
set_timezone(char *zone) {
|
||||||
|
if (zone == NULL) { assert(unsetenv("TZ") == 0); }
|
||||||
|
else { assert(setenv("TZ", zone, 1) == 0); }
|
||||||
|
tzset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mod_time(char *fmt) {
|
||||||
|
static char buf[mod_time_bufsize];
|
||||||
|
struct tm *tm;
|
||||||
|
static time_t t = 0;
|
||||||
|
static tick_t last_tick = 0;
|
||||||
|
|
||||||
|
if (ticker == 0) { t = time(NULL); }
|
||||||
|
else if (ticker != last_tick) { t += slept; }
|
||||||
|
last_tick = ticker;
|
||||||
|
assert((tm = localtime(&t)) != NULL);
|
||||||
|
assert(strftime(buf, sizeof(buf) / sizeof(*buf), fmt, tm) != 0);
|
||||||
|
|
||||||
|
out(buf);
|
||||||
|
out(get("separator"));
|
||||||
|
}
|
52
status/order.def.c
Normal file
52
status/order.def.c
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/* This is a C source file #included at global scope in status.c. There are a
|
||||||
|
* number of useful functions defined in status.c and #included headers to try
|
||||||
|
* to make iteration a little more convenient. */
|
||||||
|
|
||||||
|
/* Environment
|
||||||
|
* getenv(key) gets the value of an environment variable
|
||||||
|
* setenv(key, val, overwrite) sets key to val in the environment, overwriting
|
||||||
|
* val if key was already defined and overwrite is 0
|
||||||
|
* set_timezone(val) sets TZ to val in the environment, then calls tzset(3) to
|
||||||
|
* set appropriate timezone values. if val is NULL, it clears the TZ val,
|
||||||
|
* which restores the timezone to the system local time
|
||||||
|
* get(key) gets the val corresponding to key in settings
|
||||||
|
* set(key, val) sets the val corresponding to key in settings
|
||||||
|
* idx(key) returns the index of key in settings
|
||||||
|
* del(key) deletes the first instance of key in settings
|
||||||
|
* cpy(key) creates an identical instance to key in settings
|
||||||
|
* ren(key, dst) renames key to dst in settings
|
||||||
|
* keyval_init() cleans the settings in case of a glitch */
|
||||||
|
|
||||||
|
/* I/O
|
||||||
|
* out(s) holds s and prints what it was previously holding, if it wasn't NULL
|
||||||
|
* drop() sets out()'s held value to NULL */
|
||||||
|
|
||||||
|
/* Modules
|
||||||
|
* mod_static(s) outputs s and then the separator val, unless mod_static() is
|
||||||
|
* called as the last function in order
|
||||||
|
* mod_time(fmt) outputs the time for the current time zone in the strftime(3)
|
||||||
|
* fmt */
|
||||||
|
void
|
||||||
|
order() {
|
||||||
|
/* there are a couple good ways to print without the separator. the
|
||||||
|
* best is to use out() to write directly to the output buffer */
|
||||||
|
out("utc"); /* => "utc" */
|
||||||
|
/* but another way is to use status_static to write a message and
|
||||||
|
* separator, then use drop() to recall the last thing written (always
|
||||||
|
* the separator in status_* functions) */
|
||||||
|
mod_static(" "); drop(); /* => " " */
|
||||||
|
set_timezone("");
|
||||||
|
mod_time("%Y-%m-%dT%H:%M"); /* => "2025-03-27T00:00 // " */
|
||||||
|
|
||||||
|
/* and another way is to use the weird key-val system */
|
||||||
|
cpy("separator"); /* duplicate setting */
|
||||||
|
set("separator", " "); /* overwrite first setting */
|
||||||
|
set_timezone(NULL);
|
||||||
|
mod_static("local"); /* use first setting */
|
||||||
|
del("separator"); /* delete the first, restoring the second */
|
||||||
|
mod_time("%Y-%m-%dT%H:%M");
|
||||||
|
drop();
|
||||||
|
/* => "local 2025-03-26T18:00" */
|
||||||
|
|
||||||
|
/* all => "utc 2025-03-27T00:00 // local 2025-03-26T18:00" */
|
||||||
|
}
|
2
status/settings.def.c
Normal file
2
status/settings.def.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
set("interval_seconds", "1");
|
||||||
|
set("separator", " // ");
|
32
status/status.c
Normal file
32
status/status.c
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#undef NDEBUG /* LOAD-BEARING ASSERTS! */
|
||||||
|
#include <assert.h> /* "mod_time.c" */
|
||||||
|
#include <limits.h> /* UCHAR_MAX */
|
||||||
|
#include <stdlib.h> /* "mod_time.c" */
|
||||||
|
#include <time.h> /* "mod_time.c" */
|
||||||
|
#include <unistd.h> /* sleep(3) */
|
||||||
|
#include "libio.h" /* drop(3), out(3), "mod_static.c" */
|
||||||
|
#include "libkeyval.h" /* cpy(3), del(3), get(3), keyval_init(3), set(3),
|
||||||
|
* "mod_static.c" */
|
||||||
|
|
||||||
|
#define ever (;;)
|
||||||
|
|
||||||
|
unsigned int slept = 0;
|
||||||
|
|
||||||
|
typedef unsigned char tick_t;
|
||||||
|
#define TICK_MAX UCHAR_MAX
|
||||||
|
tick_t ticker = 0;
|
||||||
|
|
||||||
|
#include "mod_static.c"
|
||||||
|
#include "mod_time.c"
|
||||||
|
|
||||||
|
#include "order.c"
|
||||||
|
|
||||||
|
int main(int argc, char *argv) {
|
||||||
|
keyval_init();
|
||||||
|
|
||||||
|
for ever {
|
||||||
|
order(); drop(); out("\n");
|
||||||
|
slept = sleep(getd("interval_seconds"));
|
||||||
|
ticker = ++ticker % TICK_MAX;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user