diff options
145 files changed, 2363 insertions, 599 deletions
diff --git a/TOUR.7 b/TOUR.7 deleted file mode 100644 index 8466f524..00000000 --- a/TOUR.7 +++ /dev/null @@ -1,22 +0,0 @@ -.Dd March 16, 2022 -.Dt TOUR 7 -.Os "Causal Agency" -. -.Sh NAME -.Nm tour -.Nd things that are here -. -.Sh FILES -.Bl -tag -width Ds -.It Pa home/ -.Dq dotfiles -.It Pa bin/ -utilities of varying utility -.It Pa doc/rfc/ -scripts for reading IETF RFCs -.It Pa doc/zlib/ -zlib documentation ported to -.Xr mdoc 7 -.It Pa www/ -sources for causal.agency sites -.El diff --git a/agpl.c b/agpl.c index 58a88fc4..e7682757 100644 --- a/agpl.c +++ b/agpl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 June McEnroe <june@causal.agency> +/* Copyright (C) 2024 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -17,4 +17,3 @@ #include <err.h> #include <stdio.h> #include <stdlib.h> -#include <sysexits.h> diff --git a/bin/.gitignore b/bin/.gitignore index 59b60826..42269bac 100644 --- a/bin/.gitignore +++ b/bin/.gitignore @@ -24,6 +24,7 @@ pbd pngo psf2png ptee +qf quick relay scheme diff --git a/bin/Makefile b/bin/Makefile index 5d23ab3c..bb1535d6 100644 --- a/bin/Makefile +++ b/bin/Makefile @@ -26,6 +26,7 @@ BINS += pbd BINS += pngo BINS += psf2png BINS += ptee +BINS += qf BINS += quick BINS += scheme BINS += shotty @@ -55,6 +56,7 @@ LDLIBS.glitch = -lz LDLIBS.modem = -lutil LDLIBS.pngo = -lz LDLIBS.ptee = -lutil +LDLIBS.qf = -lcurses LDLIBS.relay = -ltls LDLIBS.scheme = -lm LDLIBS.title = -lcurl diff --git a/bin/README.7 b/bin/README.7 index c562e84c..100e183e 100644 --- a/bin/README.7 +++ b/bin/README.7 @@ -1,4 +1,4 @@ -.Dd January 30, 2022 +.Dd June 2, 2022 .Dt BIN 7 .Os "Causal Agency" . @@ -58,6 +58,8 @@ PNG optimizer PSF2 to PNG renderer .It Xr ptee 1 tee for PTYs +.It Xr qf 1 +grep pager .It Xr quick 1 terrible HTTP/CGI server .It Xr relay 1 diff --git a/bin/beef.c b/bin/beef.c index b2579b73..556f3088 100644 --- a/bin/beef.c +++ b/bin/beef.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 C. McEnroe <june@causal.agency> +/* Copyright (C) 2019 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/bit.y b/bin/bit.y index ab310492..1119bce6 100644 --- a/bin/bit.y +++ b/bin/bit.y @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 C. McEnroe <june@causal.agency> +/* Copyright (C) 2019 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/c11.l b/bin/c11.l index a4b8c25a..b1f0b960 100644 --- a/bin/c11.l +++ b/bin/c11.l @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 C. McEnroe <june@causal.agency> +/* Copyright (C) 2020 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/dehtml.l b/bin/dehtml.l index 3f2de592..799f0926 100644 --- a/bin/dehtml.l +++ b/bin/dehtml.l @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 C. McEnroe <june@causal.agency> +/* Copyright (C) 2021 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/downgrade.c b/bin/downgrade.c index d4c5b598..31019714 100644 --- a/bin/downgrade.c +++ b/bin/downgrade.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 C. McEnroe <june@causal.agency> +/* Copyright (C) 2021 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/dtch.c b/bin/dtch.c index 2aea53ae..026493dd 100644 --- a/bin/dtch.c +++ b/bin/dtch.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 C. McEnroe <june@causal.agency> +/* Copyright (C) 2017-2019 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/ever.c b/bin/ever.c index f983912b..f8ff943b 100644 --- a/bin/ever.c +++ b/bin/ever.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 C. McEnroe <june@causal.agency> +/* Copyright (C) 2017 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/freecell.c b/bin/freecell.c index 11bed1c0..fbc0fe22 100644 --- a/bin/freecell.c +++ b/bin/freecell.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019, 2021 C. McEnroe <june@causal.agency> +/* Copyright (C) 2019, 2021 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/git-comment.pl b/bin/git-comment.pl index 5100941f..5352702d 100644 --- a/bin/git-comment.pl +++ b/bin/git-comment.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# Copyright (C) 2021 C. McEnroe <june@causal.agency> +# Copyright (C) 2021 June McEnroe <june@causal.agency> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by diff --git a/bin/glitch.c b/bin/glitch.c index 9747f35a..d0c926f9 100644 --- a/bin/glitch.c +++ b/bin/glitch.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 C. McEnroe <june@causal.agency> +/* Copyright (C) 2018, 2021 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -14,8 +14,9 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <arpa/inet.h> #include <err.h> +#include <inttypes.h> +#include <limits.h> #include <stdbool.h> #include <stdint.h> #include <stdio.h> @@ -25,286 +26,328 @@ #include <unistd.h> #include <zlib.h> -#define PACKED __attribute__((packed)) - -#define CRC_INIT (crc32(0, Z_NULL, 0)) +#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0])) static const char *path; static FILE *file; static uint32_t crc; -static void readExpect(void *ptr, size_t size, const char *expect) { - fread(ptr, size, 1, file); - if (ferror(file)) err(EX_IOERR, "%s", path); - if (feof(file)) errx(EX_DATAERR, "%s: missing %s", path, expect); - crc = crc32(crc, ptr, size); +static void pngRead(void *ptr, size_t len, const char *desc) { + size_t n = fread(ptr, len, 1, file); + if (!n && ferror(file)) err(EX_IOERR, "%s", path); + if (!n) errx(EX_DATAERR, "%s: missing %s", path, desc); + crc = crc32(crc, ptr, len); } -static void writeExpect(const void *ptr, size_t size) { - fwrite(ptr, size, 1, file); - if (ferror(file)) err(EX_IOERR, "%s", path); - crc = crc32(crc, ptr, size); +static void pngWrite(const void *ptr, size_t len) { + size_t n = fwrite(ptr, len, 1, file); + if (!n) err(EX_IOERR, "%s", path); + crc = crc32(crc, ptr, len); } -static const uint8_t Signature[8] = "\x89PNG\r\n\x1A\n"; +static const uint8_t Sig[8] = "\x89PNG\r\n\x1A\n"; -static void readSignature(void) { - uint8_t signature[8]; - readExpect(signature, 8, "signature"); - if (0 != memcmp(signature, Signature, 8)) { +static void sigRead(void) { + uint8_t sig[sizeof(Sig)]; + pngRead(sig, sizeof(sig), "signature"); + if (memcmp(sig, Sig, sizeof(sig))) { errx(EX_DATAERR, "%s: invalid signature", path); } } -static void writeSignature(void) { - writeExpect(Signature, sizeof(Signature)); +static void sigWrite(void) { + pngWrite(Sig, sizeof(Sig)); } -struct PACKED Chunk { - uint32_t size; - char type[4]; -}; +static uint32_t u32Read(const char *desc) { + uint8_t b[4]; + pngRead(b, sizeof(b), desc); + return (uint32_t)b[0] << 24 | (uint32_t)b[1] << 16 + | (uint32_t)b[2] << 8 | (uint32_t)b[3]; +} -static const char *typeStr(struct Chunk chunk) { - static char buf[5]; - memcpy(buf, chunk.type, 4); - return buf; +static void u32Write(uint32_t x) { + uint8_t b[4] = { x >> 24 & 0xFF, x >> 16 & 0xFF, x >> 8 & 0xFF, x & 0xFF }; + pngWrite(b, sizeof(b)); } -static struct Chunk readChunk(void) { +struct Chunk { + uint32_t len; + char type[5]; +}; + +static struct Chunk chunkRead(void) { struct Chunk chunk; - readExpect(&chunk, sizeof(chunk), "chunk"); - chunk.size = ntohl(chunk.size); - crc = crc32(CRC_INIT, (Byte *)chunk.type, sizeof(chunk.type)); + chunk.len = u32Read("chunk length"); + crc = crc32(0, Z_NULL, 0); + pngRead(chunk.type, 4, "chunk type"); + chunk.type[4] = 0; return chunk; } -static void writeChunk(struct Chunk chunk) { - chunk.size = htonl(chunk.size); - writeExpect(&chunk, sizeof(chunk)); - crc = crc32(CRC_INIT, (Byte *)chunk.type, sizeof(chunk.type)); +static void chunkWrite(struct Chunk chunk) { + u32Write(chunk.len); + crc = crc32(0, Z_NULL, 0); + pngWrite(chunk.type, 4); } -static void readCrc(void) { - uint32_t expected = crc; - uint32_t found; - readExpect(&found, sizeof(found), "CRC32"); - found = ntohl(found); - if (found != expected) { - errx( - EX_DATAERR, "%s: expected CRC32 %08X, found %08X", - path, expected, found - ); - } +static void crcRead(void) { + uint32_t expect = crc; + uint32_t actual = u32Read("CRC32"); + if (actual == expect) return; + errx( + EX_DATAERR, "%s: expected CRC32 %08X, found %08X", + path, expect, actual + ); } -static void writeCrc(void) { - uint32_t net = htonl(crc); - writeExpect(&net, sizeof(net)); +static void crcWrite(void) { + u32Write(crc); } -static void skipChunk(struct Chunk chunk) { - uint8_t discard[chunk.size]; - readExpect(discard, sizeof(discard), "chunk data"); - readCrc(); +static void chunkSkip(struct Chunk chunk) { + if (!(chunk.type[0] & 0x20)) { + errx(EX_CONFIG, "%s: unsupported critical chunk %s", path, chunk.type); + } + uint8_t buf[4096]; + while (chunk.len > sizeof(buf)) { + pngRead(buf, sizeof(buf), "chunk data"); + chunk.len -= sizeof(buf); + } + if (chunk.len) pngRead(buf, chunk.len, "chunk data"); + crcRead(); } -static struct PACKED { +enum Color { + Grayscale = 0, + Truecolor = 2, + Indexed = 3, + GrayscaleAlpha = 4, + TruecolorAlpha = 6, +}; +enum Compression { + Deflate, +}; +enum FilterMethod { + Adaptive, +}; +enum Interlace { + Progressive, + Adam7, +}; + +enum { HeaderLen = 13 }; +static struct { uint32_t width; uint32_t height; uint8_t depth; - enum PACKED { - Grayscale = 0, - Truecolor = 2, - Indexed = 3, - GrayscaleAlpha = 4, - TruecolorAlpha = 6, - } color; + uint8_t color; uint8_t compression; uint8_t filter; uint8_t interlace; } header; -_Static_assert(13 == sizeof(header), "header size"); -static size_t pixelBits(void) { +static size_t pixelLen; +static size_t lineLen; +static size_t dataLen; + +static void recalc(void) { + size_t pixelBits = header.depth; switch (header.color) { - case Grayscale: return 1 * header.depth; - case Truecolor: return 3 * header.depth; - case Indexed: return 1 * header.depth; - case GrayscaleAlpha: return 2 * header.depth; - case TruecolorAlpha: return 4 * header.depth; - default: abort(); + break; case GrayscaleAlpha: pixelBits *= 2; + break; case Truecolor: pixelBits *= 3; + break; case TruecolorAlpha: pixelBits *= 4; } + pixelLen = (pixelBits + 7) / 8; + lineLen = (header.width * pixelBits + 7) / 8; + dataLen = (1 + lineLen) * header.height; } -static size_t pixelSize(void) { - return (pixelBits() + 7) / 8; +static void headerRead(struct Chunk chunk) { + if (chunk.len != HeaderLen) { + errx( + EX_DATAERR, "%s: expected %s length %" PRIu32 ", found %" PRIu32, + path, chunk.type, (uint32_t)HeaderLen, chunk.len + ); + } + header.width = u32Read("header width"); + header.height = u32Read("header height"); + pngRead(&header.depth, 1, "header depth"); + pngRead(&header.color, 1, "header color"); + pngRead(&header.compression, 1, "header compression"); + pngRead(&header.filter, 1, "header filter"); + pngRead(&header.interlace, 1, "header interlace"); + crcRead(); + recalc(); +} + +static void headerWrite(void) { + struct Chunk ihdr = { HeaderLen, "IHDR" }; + chunkWrite(ihdr); + u32Write(header.width); + u32Write(header.height); + pngWrite(&header.depth, 1); + pngWrite(&header.color, 1); + pngWrite(&header.compression, 1); + pngWrite(&header.filter, 1); + pngWrite(&header.interlace, 1); + crcWrite(); } -static size_t lineSize(void) { - return (header.width * pixelBits() + 7) / 8; -} +static struct { + uint32_t len; + uint8_t rgb[256][3]; +} pal; -static size_t dataSize(void) { - return (1 + lineSize()) * header.height; +static struct { + uint32_t len; + uint8_t a[256]; +} trans; + +static void palClear(void) { + pal.len = 0; + trans.len = 0; } -static void readHeader(void) { - struct Chunk ihdr = readChunk(); - if (0 != memcmp(ihdr.type, "IHDR", 4)) { - errx(EX_DATAERR, "%s: expected IHDR, found %s", path, typeStr(ihdr)); +static void palRead(struct Chunk chunk) { + if (chunk.len % 3) { + errx( + EX_DATAERR, "%s: %s length %" PRIu32 " not divisible by 3", + path, chunk.type, chunk.len + ); } - if (ihdr.size != sizeof(header)) { + pal.len = chunk.len / 3; + if (pal.len > 256) { errx( - EX_DATAERR, "%s: expected IHDR size %zu, found %u", - path, sizeof(header), ihdr.size + EX_DATAERR, "%s: %s length %" PRIu32 " > 256", + path, chunk.type, pal.len ); } - readExpect(&header, sizeof(header), "header"); - readCrc(); - header.width = ntohl(header.width); - header.height = ntohl(header.height); - if (!header.width) errx(EX_DATAERR, "%s: invalid width 0", path); - if (!header.height) errx(EX_DATAERR, "%s: invalid height 0", path); + pngRead(pal.rgb, chunk.len, "palette data"); + crcRead(); } -static void writeHeader(void) { - struct Chunk ihdr = { .size = sizeof(header), .type = "IHDR" }; - writeChunk(ihdr); - header.width = htonl(header.width); - header.height = htonl(header.height); - writeExpect(&header, sizeof(header)); - writeCrc(); - header.width = ntohl(header.width); - header.height = ntohl(header.height); +static void palWrite(void) { + struct Chunk plte = { 3 * pal.len, "PLTE" }; + chunkWrite(plte); + pngWrite(pal.rgb, plte.len); + crcWrite(); } -static struct { - uint32_t len; - uint8_t entries[256][3]; -} palette; - -static void readPalette(void) { - struct Chunk chunk; - for (;;) { - chunk = readChunk(); - if (0 == memcmp(chunk.type, "PLTE", 4)) break; - skipChunk(chunk); +static void transRead(struct Chunk chunk) { + trans.len = chunk.len; + if (trans.len > 256) { + errx( + EX_DATAERR, "%s: %s length %" PRIu32 " > 256", + path, chunk.type, trans.len + ); } - palette.len = chunk.size / 3; - readExpect(palette.entries, chunk.size, "palette data"); - readCrc(); + pngRead(trans.a, chunk.len, "transparency data"); + crcRead(); } -static void writePalette(void) { - struct Chunk plte = { .size = 3 * palette.len, .type = "PLTE" }; - writeChunk(plte); - writeExpect(palette.entries, plte.size); - writeCrc(); +static void transWrite(void) { + struct Chunk trns = { trans.len, "tRNS" }; + chunkWrite(trns); + pngWrite(trans.a, trns.len); + crcWrite(); } static uint8_t *data; -static void readData(void) { - data = malloc(dataSize()); - if (!data) err(EX_OSERR, "malloc(%zu)", dataSize()); +static void dataAlloc(void) { + data = malloc(dataLen); + if (!data) err(EX_OSERR, "malloc"); +} - struct z_stream_s stream = { .next_out = data, .avail_out = dataSize() }; +static void dataRead(struct Chunk chunk) { + z_stream stream = { .next_out = data, .avail_out = dataLen }; int error = inflateInit(&stream); - if (error != Z_OK) errx(EX_SOFTWARE, "%s: inflateInit: %s", path, stream.msg); + if (error != Z_OK) errx(EX_SOFTWARE, "inflateInit: %s", stream.msg); for (;;) { - struct Chunk chunk = readChunk(); - if (0 == memcmp(chunk.type, "IDAT", 4)) { - uint8_t *idat = malloc(chunk.size); - if (!idat) err(EX_OSERR, "malloc"); - - readExpect(idat, chunk.size, "image data"); - readCrc(); + if (strcmp(chunk.type, "IDAT")) { + errx(EX_DATAERR, "%s: missing IDAT chunk", path); + } - stream.next_in = idat; - stream.avail_in = chunk.size; - int error = inflate(&stream, Z_SYNC_FLUSH); - free(idat); + uint8_t *idat = malloc(chunk.len); + if (!idat) err(EX_OSERR, "malloc"); - if (error == Z_STREAM_END) break; - if (error != Z_OK) errx(EX_DATAERR, "%s: inflate: %s", path, stream.msg); + pngRead(idat, chunk.len, "image data"); + crcRead(); + + stream.next_in = idat; + stream.avail_in = chunk.len; + error = inflate(&stream, Z_SYNC_FLUSH); + free(idat); - } else if (0 == memcmp(chunk.type, "IEND", 4)) { - errx(EX_DATAERR, "%s: missing IDAT chunk", path); - } else { - skipChunk(chunk); + if (error == Z_STREAM_END) break; + if (error != Z_OK) { + errx(EX_DATAERR, "%s: inflate: %s", path, stream.msg); } - } + chunk = chunkRead(); + } inflateEnd(&stream); - if ((size_t)stream.total_out != dataSize()) { + if ((size_t)stream.total_out != dataLen) { errx( - EX_DATAERR, "%s: expected data size %zu, found %zu", - path, dataSize(), (size_t)stream.total_out + EX_DATAERR, "%s: expected data length %zu, found %zu", + path, dataLen, (size_t)stream.total_out ); } } -static void writeData(void) { - uLong size = compressBound(dataSize()); - uint8_t *deflate = malloc(size); - if (!deflate) err(EX_OSERR, "malloc"); +static void dataWrite(void) { + z_stream stream = { + .next_in = data, + .avail_in = dataLen, + }; + int error = deflateInit2( + &stream, Z_BEST_COMPRESSION, Z_DEFLATED, 15, 8, Z_FILTERED + ); + if (error != Z_OK) errx(EX_SOFTWARE, "deflateInit2: %s", stream.msg); - int error = compress2(deflate, &size, data, dataSize(), Z_BEST_SPEED); - if (error != Z_OK) errx(EX_SOFTWARE, "%s: compress2: %d", path, error); + uLong bound = deflateBound(&stream, dataLen); + uint8_t *buf = malloc(bound); + if (!buf) err(EX_OSERR, "malloc"); - struct Chunk idat = { .size = size, .type = "IDAT" }; - writeChunk(idat); - writeExpect(deflate, size); - writeCrc(); + stream.next_out = buf; + stream.avail_out = bound; + deflate(&stream, Z_FINISH); + deflateEnd(&stream); - free(deflate); -} + struct Chunk idat = { stream.total_out, "IDAT" }; + chunkWrite(idat); + pngWrite(buf, stream.total_out); + crcWrite(); + free(buf); -static void writeEnd(void) { - struct Chunk iend = { .size = 0, .type = "IEND" }; - writeChunk(iend); - writeCrc(); + struct Chunk iend = { 0, "IEND" }; + chunkWrite(iend); + crcWrite(); } -enum PACKED Filter { +enum Filter { None, Sub, Up, Average, Paeth, - FilterCount, + FilterCap, }; -static struct { - bool brokenPaeth; - bool filt; - bool recon; - uint8_t declareFilter; - uint8_t applyFilter; - enum Filter declareFilters[255]; - enum Filter applyFilters[255]; - bool invert; - bool mirror; - bool zeroX; - bool zeroY; -} options; - struct Bytes { - uint8_t x; - uint8_t a; - uint8_t b; - uint8_t c; + uint8_t x, a, b, c; }; +static bool brokenPaeth; static uint8_t paethPredictor(struct Bytes f) { int32_t p = (int32_t)f.a + (int32_t)f.b - (int32_t)f.c; - int32_t pa = abs(p - (int32_t)f.a); - int32_t pb = abs(p - (int32_t)f.b); - int32_t pc = abs(p - (int32_t)f.c); + int32_t pa = labs(p - (int32_t)f.a); + int32_t pb = labs(p - (int32_t)f.b); + int32_t pc = labs(p - (int32_t)f.c); if (pa <= pb && pa <= pc) return f.a; - if (options.brokenPaeth) { + if (brokenPaeth) { if (pb < pc) return f.b; } else { if (pb <= pc) return f.b; @@ -319,7 +362,7 @@ static uint8_t recon(enum Filter type, struct Bytes f) { case Up: return f.x + f.b; case Average: return f.x + ((uint32_t)f.a + (uint32_t)f.b) / 2; case Paeth: return f.x + paethPredictor(f); - default: abort(); + default: abort(); } } @@ -330,59 +373,59 @@ static uint8_t filt(enum Filter type, struct Bytes f) { case Up: return f.x - f.b; case Average: return f.x - ((uint32_t)f.a + (uint32_t)f.b) / 2; case Paeth: return f.x - paethPredictor(f); - default: abort(); + default: abort(); } } -static struct Line { - enum Filter type; - uint8_t data[]; -} **lines; - -static void scanlines(void) { - lines = calloc(header.height, sizeof(*lines)); - if (!lines) err(EX_OSERR, "calloc(%u, %zu)", header.height, sizeof(*lines)); - - size_t stride = 1 + lineSize(); - for (uint32_t y = 0; y < header.height; ++y) { - lines[y] = (struct Line *)&data[y * stride]; - if (lines[y]->type >= FilterCount) { - errx(EX_DATAERR, "%s: invalid filter type %hhu", path, lines[y]->type); - } - } +static uint8_t *lineType(uint32_t y) { + return &data[y * (1 + lineLen)]; +} +static uint8_t *lineData(uint32_t y) { + return 1 + lineType(y); } static struct Bytes origBytes(uint32_t y, size_t i) { - bool a = (i >= pixelSize()), b = (y > 0), c = (a && b); + bool a = (i >= pixelLen), b = (y > 0), c = (a && b); return (struct Bytes) { - .x = lines[y]->data[i], - .a = a ? lines[y]->data[i - pixelSize()] : 0, - .b = b ? lines[y - 1]->data[i] : 0, - .c = c ? lines[y - 1]->data[i - pixelSize()] : 0, + .x = lineData(y)[i], + .a = (a ? lineData(y)[i-pixelLen] : 0), + .b = (b ? lineData(y-1)[i] : 0), + .c = (c ? lineData(y-1)[i-pixelLen] : 0), }; } -static void reconData(void) { +static bool reconFilter; +static void dataRecon(void) { for (uint32_t y = 0; y < header.height; ++y) { - for (size_t i = 0; i < lineSize(); ++i) { - if (options.filt) { - lines[y]->data[i] = filt(lines[y]->type, origBytes(y, i)); + for (size_t i = 0; i < lineLen; ++i) { + if (reconFilter) { + lineData(y)[i] = filt(*lineType(y), origBytes(y, i)); } else { - lines[y]->data[i] = recon(lines[y]->type, origBytes(y, i)); + lineData(y)[i] = recon(*lineType(y), origBytes(y, i)); } } - lines[y]->type = None; + *lineType(y) = None; } } -static void filterData(void) { - for (uint32_t y = header.height - 1; y < header.height; --y) { - uint8_t filter[FilterCount][lineSize()]; - uint32_t heuristic[FilterCount] = {0}; +static bool filterRecon; +static size_t applyFilter; +static enum Filter applyFilters[256]; +static size_t declFilter; +static enum Filter declFilters[256]; + +static void dataFilter(void) { + uint8_t *filter[FilterCap]; + for (enum Filter i = None; i < FilterCap; ++i) { + filter[i] = malloc(lineLen); + if (!filter[i]) err(EX_OSERR, "malloc"); + } + for (uint32_t y = header.height-1; y < header.height; --y) { + uint32_t heuristic[FilterCap] = {0}; enum Filter minType = None; - for (enum Filter type = None; type < FilterCount; ++type) { - for (size_t i = 0; i < lineSize(); ++i) { - if (options.recon) { + for (enum Filter type = None; type < FilterCap; ++type) { + for (size_t i = 0; i < lineLen; ++i) { + if (filterRecon) { filter[type][i] = recon(type, origBytes(y, i)); } else { filter[type][i] = filt(type, origBytes(y, i)); @@ -391,49 +434,26 @@ static void filterData(void) { } if (heuristic[type] < heuristic[minType]) minType = type; } - - if (options.declareFilter) { - lines[y]->type = options.declareFilters[y % options.declareFilter]; + if (declFilter) { + *lineType(y) = declFilters[y % declFilter]; } else { - lines[y]->type = minType; + *lineType(y) = minType; } - - if (options.applyFilter) { - enum Filter type = options.applyFilters[y % options.applyFilter]; - memcpy(lines[y]->data, filter[type], lineSize()); + if (applyFilter) { + memcpy(lineData(y), filter[applyFilters[y % applyFilter]], lineLen); } else { - memcpy(lines[y]->data, filter[minType], lineSize()); + memcpy(lineData(y), filter[minType], lineLen); } } -} - -static void invert(void) { - for (uint32_t y = 0; y < header.height; ++y) { - for (size_t i = 0; i < lineSize(); ++i) { - lines[y]->data[i] ^= 0xFF; - } - } -} - -static void mirror(void) { - for (uint32_t y = 0; y < header.height; ++y) { - for (size_t i = 0, j = lineSize() - 1; i < j; ++i, --j) { - uint8_t t = lines[y]->data[i]; - lines[y]->data[i] = lines[y]->data[j]; - lines[y]->data[j] = t; - } - } -} - -static void zeroX(void) { - for (uint32_t y = 0; y < header.height; ++y) { - memset(lines[y]->data, 0, pixelSize()); + for (enum Filter i = None; i < FilterCap; ++i) { + free(filter[i]); } } -static void zeroY(void) { - memset(lines[0]->data, 0, lineSize()); -} +static bool invertData; +static bool mirrorData; +static bool zeroX; +static bool zeroY; static void glitch(const char *inPath, const char *outPath) { if (inPath) { @@ -441,98 +461,145 @@ static void glitch(const char *inPath, const char *outPath) { file = fopen(path, "r"); if (!file) err(EX_NOINPUT, "%s", path); } else { - path = "(stdin)"; + path = "stdin"; file = stdin; } - readSignature(); - readHeader(); - if (header.color == Indexed) readPalette(); - readData(); + sigRead(); + struct Chunk ihdr = chunkRead(); + if (strcmp(ihdr.type, "IHDR")) { + errx(EX_DATAERR, "%s: expected IHDR, found %s", path, ihdr.type); + } + headerRead(ihdr); + if (header.interlace != Progressive) { + errx(EX_CONFIG, "%s: unsupported interlacing", path); + } + + palClear(); + dataAlloc(); + for (;;) { + struct Chunk chunk = chunkRead(); + if (!strcmp(chunk.type, "PLTE")) { + palRead(chunk); + } else if (!strcmp(chunk.type, "tRNS")) { + transRead(chunk); + } else if (!strcmp(chunk.type, "IDAT")) { + dataRead(chunk); + } else if (!strcmp(chunk.type, "IEND")) { + break; + } else { + chunkSkip(chunk); + } + } fclose(file); - scanlines(); - reconData(); - filterData(); - if (options.invert) invert(); - if (options.mirror) mirror(); - if (options.zeroX) zeroX(); - if (options.zeroY) zeroY(); - free(lines); + dataRecon(); + dataFilter(); + if (invertData) { + for (uint32_t y = 0; y < header.height; ++y) { + for (size_t i = 0; i < lineLen; ++i) { + lineData(y)[i] ^= 0xFF; + } + } + } + if (mirrorData) { + for (uint32_t y = 0; y < header.height; ++y) { + for (size_t i = 0, j = lineLen-1; i < j; ++i, --j) { + uint8_t x = lineData(y)[i]; + lineData(y)[i] = lineData(y)[j]; + lineData(y)[j] = x; + } + } + } + if (zeroX) { + for (uint32_t y = 0; y < header.height; ++y) { + memset(lineData(y), 0, pixelLen); + } + } + if (zeroY) { + memset(lineData(0), 0, lineLen); + } + + char buf[PATH_MAX]; if (outPath) { path = outPath; - file = fopen(path, "w"); - if (!file) err(EX_CANTCREAT, "%s", path); + if (outPath == inPath) { + snprintf(buf, sizeof(buf), "%sg", outPath); + file = fopen(buf, "wx"); + if (!file) err(EX_CANTCREAT, "%s", buf); + } else { + file = fopen(path, "w"); + if (!file) err(EX_CANTCREAT, "%s", outPath); + } } else { - path = "(stdout)"; + path = "stdout"; file = stdout; } - writeSignature(); - writeHeader(); - if (header.color == Indexed) writePalette(); - writeData(); - writeEnd(); + sigWrite(); + headerWrite(); + if (header.color == Indexed) { + palWrite(); + if (trans.len) transWrite(); + } + dataWrite(); free(data); - int error = fclose(file); if (error) err(EX_IOERR, "%s", path); + + if (outPath && outPath == inPath) { + error = rename(buf, outPath); + if (error) err(EX_CANTCREAT, "%s", outPath); + } } -static enum Filter parseFilter(const char *s) { - switch (s[0]) { +static enum Filter parseFilter(const char *str) { + switch (str[0]) { case 'N': case 'n': return None; case 'S': case 's': return Sub; case 'U': case 'u': return Up; case 'A': case 'a': return Average; case 'P': case 'p': return Paeth; - default: errx(EX_USAGE, "invalid filter type %s", s); + default: errx(EX_USAGE, "invalid filter type %s", str); } } -static uint8_t parseFilters(enum Filter *filters, const char *s) { - uint8_t len = 0; - do { - filters[len++] = parseFilter(s); - s = strchr(s, ','); - } while (s++); +static size_t parseFilters(enum Filter *filters, char *str) { + size_t len = 0; + while (str) { + char *filt = strsep(&str, ","); + filters[len++] = parseFilter(filt); + } return len; } int main(int argc, char *argv[]) { bool stdio = false; - char *output = NULL; + char *outPath = NULL; - int opt; - while (0 < (opt = getopt(argc, argv, "a:cd:fimo:prxy"))) { + for (int opt; 0 < (opt = getopt(argc, argv, "a:cd:fimo:prxy"));) { switch (opt) { - break; case 'a': - options.applyFilter = parseFilters(options.applyFilters, optarg); + break; case 'a': applyFilter = parseFilters(applyFilters, optarg); break; case 'c': stdio = true; - break; case 'd': - options.declareFilter = parseFilters(options.declareFilters, optarg); - break; case 'f': options.filt = true; - break; case 'i': options.invert = true; - break; case 'm': options.mirror = true; - break; case 'o': output = optarg; - break; case 'p': options.brokenPaeth = true; - break; case 'r': options.recon = true; - break; case 'x': options.zeroX = true; - break; case 'y': options.zeroY = true; - break; default: return EX_USAGE; + break; case 'd': declFilter = parseFilters(declFilters, optarg); + break; case 'f': reconFilter = true; + break; case 'i': invertData = true; + break; case 'm': mirrorData = true; + break; case 'o': outPath = optarg; + break; case 'p': brokenPaeth = true; + break; case 'r': filterRecon = true; + break; case 'x': zeroX = true; + break; case 'y': zeroY = true; + break; default: return EX_USAGE; } } - if (argc - optind == 1 && (output || stdio)) { - glitch(argv[optind], output); - } else if (optind < argc) { + if (optind < argc) { for (int i = optind; i < argc; ++i) { - glitch(argv[i], argv[i]); + glitch(argv[i], (stdio ? NULL : outPath ? outPath : argv[i])); } } else { - glitch(NULL, output); + glitch(NULL, outPath); } - - return EX_OK; } diff --git a/bin/hilex.c b/bin/hilex.c index 0bcc5c7f..7d7b3f2d 100644 --- a/bin/hilex.c +++ b/bin/hilex.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 C. McEnroe <june@causal.agency> +/* Copyright (C) 2020 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -53,7 +53,7 @@ static const struct { { &LexC, "c", "[.][chlmy]$", NULL }, { &LexMake, "make", "[.](mk|am)$|^Makefile$", NULL }, { &LexMdoc, "mdoc", "[.][1-9]$", "^[.]Dd" }, - { &LexSh, "sh", "[.]sh$|^[.](profile|shrc)$", "^#![ ]?/bin/sh" }, + { &LexSh, "sh", "[.]sh$|^[.](profile|shrc)$", "^#![ ]?/bin/k?sh" }, { &LexText, "text", "[.]txt$", NULL }, }; diff --git a/bin/hilex.h b/bin/hilex.h index 882b5f95..b57fc8cc 100644 --- a/bin/hilex.h +++ b/bin/hilex.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 C. McEnroe <june@causal.agency> +/* Copyright (C) 2020 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/make.l b/bin/make.l index ae1be2f5..6296716d 100644 --- a/bin/make.l +++ b/bin/make.l @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 C. McEnroe <june@causal.agency> +/* Copyright (C) 2020 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/man1/qf.1 b/bin/man1/qf.1 new file mode 100644 index 00000000..8828d723 --- /dev/null +++ b/bin/man1/qf.1 @@ -0,0 +1,71 @@ +.Dd June 2, 2022 +.Dt QF 1 +.Os +. +.Sh NAME +.Nm qf +.Nd grep pager +. +.Sh SYNOPSIS +.Nm Op Ar pattern +. +.Sh DESCRIPTION +.Nm +is a pager for +.Xr grep 1 , +.Xr ag 1 , +.Xr rg 1 , +etc.\& +which allows +jumping to matches in +.Ev $EDITOR . +It parses any input +prefixed by path +and line number +separated by a colon +.Ql ":" +followed by either a colon +or a hyphen +.Ql "-" . +It otherwise operates similar to +.Xr less 1 . +. +.Pp +If +.Ar pattern +is given, +the first match on each line +will be highlighted. +The +.Ar pattern +is interpreted as +an extended regular expression +and is matched case-insensitively +unless it contains an uppercase letter. +. +.Pp +The keys are as follows: +.Bl -tag -width Ds +.It Ic Enter +Open the currently selected line in +.Ev $EDITOR . +When the editor exits, +.Nm +resumes. +.It Ic {} +Jump between files. +.It Ic gG +Jump to first or last line. +.It Ic jk +Move to next or previous line. +.It Ic nN +Jump to next or previous match line. +.It Ic q +Exit. +.It Ic r +Refresh the display. +.El +. +.Sh EXAMPLES +.Dl $ ag -C open | qf +.Dl $ git grep -n open | qf diff --git a/bin/man1/up.1 b/bin/man1/up.1 index 2240b99a..aece79bd 100644 --- a/bin/man1/up.1 +++ b/bin/man1/up.1 @@ -1,4 +1,4 @@ -.Dd June 21, 2021 +.Dd July 26, 2022 .Dt UP 1 .Os . @@ -8,15 +8,9 @@ . .Sh SYNOPSIS .Nm -.Op Fl h -.Op Ar file -. -.Nm -.Fl c | t -.Ar command -. -.Nm -.Fl s +.Op Fl c | h | s | t +.Op Fl w Ar warn +.Op Ar file | command . .Sh DESCRIPTION .Nm @@ -65,6 +59,10 @@ Run a command with and .Xr shotty 1 to produce an HTML file for upload. +.It Fl w Ar warn +Create an HTML redirect with +.Ar warn +in its title. .El . .Pp diff --git a/bin/man1/when.1 b/bin/man1/when.1 index 0b473573..3f2735f7 100644 --- a/bin/man1/when.1 +++ b/bin/man1/when.1 @@ -1,4 +1,4 @@ -.Dd July 24, 2019 +.Dd September 19, 2022 .Dt WHEN 1 .Os . @@ -9,6 +9,8 @@ .Sh SYNOPSIS .Nm .Op Ar expr +.Nm +.Cm - . .Sh DESCRIPTION .Nm @@ -18,24 +20,32 @@ If no is given, expressions are read from standard input. +If +.Cm - +is given, +the intervals between each named date +and today are printed. . .Pp The grammar is as follows: .Bl -tag -width Ds .It Sy \&. Today's date. +The empty expression is equivalent. +. +.It Ar name Op Sy = Ar date +A named date. +Names are alphanumeric including underscores. . .It Ar month Ar date Op Ar year A full date, or a date in the current year. -.Ar month -must be at least three letters. +Months can be abbreviated to three letters. . .It Ar day A day of the week in the current week. -.Ar day -must be at least three letters. +Days can be abbreviated to three letters. . .It Sy < Ar date The date one week before. @@ -65,6 +75,14 @@ A number of months. A number of years. .El . +.Sh FILES +The file +.Pa $XDG_CONFIG_HOME/when/dates +or +.Pa ~/.config/when/dates +is read before any other expressions, +if it exists. +. .Sh EXAMPLES .Bl -tag -width "Dec 25 - ." .It Ic Dec 25 - \&. @@ -74,3 +92,9 @@ The date next Friday. .It Ic \&. + 2w Your last day at work. .El +.Pp +Checking a milestone: +.Bd -literal -offset indent +$ echo 'hrt = oct 15 2021' >> ~/.config/when/dates +$ when -hrt +.Ed diff --git a/bin/mdoc.l b/bin/mdoc.l index f29b6ceb..b6deacbe 100644 --- a/bin/mdoc.l +++ b/bin/mdoc.l @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 C. McEnroe <june@causal.agency> +/* Copyright (C) 2020 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/modem.c b/bin/modem.c index 2133ae08..4392e071 100644 --- a/bin/modem.c +++ b/bin/modem.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 C. McEnroe <june@causal.agency> +/* Copyright (C) 2018 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/mtags.c b/bin/mtags.c index 11cd9c8a..5c1a057e 100644 --- a/bin/mtags.c +++ b/bin/mtags.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 C. McEnroe <june@causal.agency> +/* Copyright (C) 2021 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/nudge.c b/bin/nudge.c index 108d2459..8ae916eb 100644 --- a/bin/nudge.c +++ b/bin/nudge.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 C. McEnroe <june@causal.agency> +/* Copyright (C) 2020 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/order.y b/bin/order.y index c2e87971..b3cbf2df 100644 --- a/bin/order.y +++ b/bin/order.y @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 C. McEnroe <june@causal.agency> +/* Copyright (C) 2019 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/pbd.c b/bin/pbd.c index 2fd401ae..9f47b63e 100644 --- a/bin/pbd.c +++ b/bin/pbd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 C. McEnroe <june@causal.agency> +/* Copyright (C) 2017 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/png.h b/bin/png.h index 15b6d13d..0df4699b 100644 --- a/bin/png.h +++ b/bin/png.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 C. McEnroe <june@causal.agency> +/* Copyright (C) 2018 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/pngo.c b/bin/pngo.c index ba90889a..eb51ccc2 100644 --- a/bin/pngo.c +++ b/bin/pngo.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018, 2021 C. McEnroe <june@causal.agency> +/* Copyright (C) 2018, 2021 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/psf2png.c b/bin/psf2png.c index 1aaa8635..c36238a0 100644 --- a/bin/psf2png.c +++ b/bin/psf2png.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 C. McEnroe <june@causal.agency> +/* Copyright (C) 2018 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/ptee.c b/bin/ptee.c index 8374bd8f..52350a21 100644 --- a/bin/ptee.c +++ b/bin/ptee.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 C. McEnroe <june@causal.agency> +/* Copyright (C) 2019 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/qf.c b/bin/qf.c new file mode 100644 index 00000000..1fbf48b9 --- /dev/null +++ b/bin/qf.c @@ -0,0 +1,294 @@ +/* Copyright (C) 2022 June McEnroe <june@causal.agency> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <ctype.h> +#include <curses.h> +#include <err.h> +#include <fcntl.h> +#include <poll.h> +#include <regex.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/wait.h> +#include <sysexits.h> +#include <unistd.h> + +enum Type { + File, + Match, + Context, + Text, +}; + +struct Line { + enum Type type; + char *path; + unsigned nr; + char *text; + regmatch_t match; +}; + +static struct { + struct Line *ptr; + size_t len, cap; +} lines; + +static void push(struct Line line) { + if (lines.len == lines.cap) { + lines.cap = (lines.cap ? lines.cap * 2 : 256); + lines.ptr = realloc(lines.ptr, sizeof(*lines.ptr) * lines.cap); + if (!lines.ptr) err(EX_OSERR, "realloc"); + } + lines.ptr[lines.len++] = line; +} + +static const char *pattern; +static regex_t regex; + +static void parse(struct Line line) { + line.path = strsep(&line.text, ":"); + if (!line.text) { + line.type = Text; + line.text = line.path; + if (lines.len) line.path = lines.ptr[lines.len-1].path; + push(line); + return; + } + char *rest; + line.nr = strtoul(line.text, &rest, 10); + struct Line prev = {0}; + if (lines.len) prev = lines.ptr[lines.len-1]; + if (!prev.path || strcmp(line.path, prev.path)) { + if (lines.len) push((struct Line) { .type = Text, .text = " " }); + line.type = File; + push(line); + } + if (rest > line.text && rest[0] == ':') { + line.type = Match; + line.text = &rest[1]; + } else if (rest > line.text && rest[0] == '-') { + line.type = Context; + line.text = &rest[1]; + } else { + line.type = Text; + } + if (line.type == Match && pattern) { + regexec(®ex, line.text, 1, &line.match, 0); + } + push(line); +} + +enum { + Path = 1, + Number = 2, + Highlight = 3, +}; + +static void curse(void) { + set_term(newterm(NULL, stdout, stderr)); + cbreak(); + noecho(); + nodelay(stdscr, true); + TABSIZE = 4; + curs_set(0); + start_color(); + use_default_colors(); + init_pair(Path, COLOR_GREEN, -1); + init_pair(Number, COLOR_YELLOW, -1); + init_pair(Highlight, COLOR_MAGENTA, -1); +} + +static size_t top; +static size_t cur; +static bool reading = true; + +static void draw(void) { + int y = 0, x = 0; + for (int i = 0; i < LINES; ++i) { + move(i, 0); + clrtoeol(); + if (top + i >= lines.len) { + addstr(reading ? "..." : !lines.len ? "No results" : ""); + break; + } + struct Line line = lines.ptr[top + i]; + if (top + i == cur) { + getyx(stdscr, y, x); + attron(A_REVERSE); + } else { + attroff(A_REVERSE); + } + switch (line.type) { + break; case File: { + color_set(Path, NULL); + addstr(line.path); + color_set(0, NULL); + } + break; case Match: { + color_set(Number, NULL); + printw("%u", line.nr); + color_set(0, NULL); + addch(':'); + if (line.match.rm_so == line.match.rm_eo) { + addstr(line.text); + break; + } + addnstr(line.text, line.match.rm_so); + color_set(Highlight, NULL); + addnstr( + &line.text[line.match.rm_so], + line.match.rm_eo - line.match.rm_so + ); + color_set(0, NULL); + addstr(&line.text[line.match.rm_eo]); + } + break; case Context: { + color_set(Number, NULL); + printw("%u", line.nr); + color_set(0, NULL); + addch('-'); + addstr(line.text); + } + break; case Text: addstr(line.text); + } + } + move(y, x); + refresh(); +} + +static void edit(struct Line line) { + char cmd[32]; + snprintf(cmd, sizeof(cmd), "+%u", (line.nr ? line.nr : 1)); + const char *editor = getenv("EDITOR"); + if (!editor) editor = "vi"; + pid_t pid = fork(); + if (pid < 0) err(EX_OSERR, "fork"); + if (!pid) { + dup2(STDERR_FILENO, STDIN_FILENO); + execlp(editor, editor, cmd, line.path, NULL); + err(EX_CONFIG, "%s", editor); + } + int status; + pid = waitpid(pid, &status, 0); + if (pid < 0) err(EX_OSERR, "waitpid"); +} + +static void toPrev(enum Type type) { + if (!cur) return; + size_t prev = cur - 1; + while (prev && lines.ptr[prev].type != type) { + prev--; + } + if (lines.ptr[prev].type == type) { + cur = prev; + } +} + +static void toNext(enum Type type) { + size_t next = cur + 1; + while (next < lines.len && lines.ptr[next].type != type) { + next++; + } + if (next < lines.len && lines.ptr[next].type == type) { + cur = next; + } +} + +static void input(void) { + char ch; + while (ERR != (ch = getch())) { + switch (ch) { + break; case '\n': { + if (lines.ptr[cur].type == Text) break; + endwin(); + edit(lines.ptr[cur]); + refresh(); + } + break; case '{': toPrev(File); + break; case '}': toNext(File); + break; case 'G': cur = lines.len - 1; + break; case 'N': toPrev(Match); + break; case 'g': cur = 0; + break; case 'j': if (cur + 1 < lines.len) cur++; + break; case 'k': if (cur) cur--; + break; case 'n': toNext(Match); + break; case 'q': { + endwin(); + exit(EX_OK); + } + break; case 'r': clearok(stdscr, true); + } + } + if (cur < top) top = cur; + if (cur >= top + LINES) top = cur - LINES + 1; +} + +int main(int argc, char *argv[]) { + if (isatty(STDIN_FILENO)) errx(EX_USAGE, "no input"); + if (argc > 1) { + pattern = argv[1]; + int flags = REG_EXTENDED | REG_ICASE; + for (const char *ch = pattern; *ch; ++ch) { + if (isupper(*ch)) { + flags &= ~REG_ICASE; + break; + } + } + int error = regcomp(®ex, pattern, flags); + if (error) errx(EX_USAGE, "invalid pattern"); + } + curse(); + draw(); + struct pollfd fds[2] = { + { .fd = STDERR_FILENO, .events = POLLIN }, + { .fd = STDIN_FILENO, .events = POLLIN }, + }; + size_t len = 0; + size_t cap = 4096; + char *buf = malloc(cap); + if (!buf) err(EX_OSERR, "malloc"); + while (poll(fds, (reading ? 2 : 1), -1)) { + if (fds[0].revents) { + input(); + } + if (reading && fds[1].revents) { + ssize_t n = read(fds[1].fd, &buf[len], cap - len); + if (n < 0) err(EX_IOERR, "read"); + if (!n) reading = false; + len += n; + char *ptr = buf; + for ( + char *nl; + (nl = memchr(ptr, '\n', &buf[len] - ptr)); + ptr = &nl[1] + ) { + struct Line line = { .text = strndup(ptr, nl - ptr) }; + if (!line.text) err(EX_OSERR, "strndup"); + parse(line); + } + len -= ptr - buf; + memmove(buf, ptr, len); + if (len == cap) { + cap *= 2; + buf = realloc(buf, cap); + if (!buf) err(EX_OSERR, "realloc"); + } + } + draw(); + } + err(EX_IOERR, "poll"); +} diff --git a/bin/quick.c b/bin/quick.c index edf35a3b..d814873d 100644 --- a/bin/quick.c +++ b/bin/quick.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 C. McEnroe <june@causal.agency> +/* Copyright (C) 2021 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/relay.c b/bin/relay.c index aa7913c9..fd799462 100644 --- a/bin/relay.c +++ b/bin/relay.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 C. McEnroe <june@causal.agency> +/* Copyright (C) 2019 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/scheme.c b/bin/scheme.c index 33fd8b60..2bae8f82 100644 --- a/bin/scheme.c +++ b/bin/scheme.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018, 2019 C. McEnroe <june@causal.agency> +/* Copyright (C) 2018, 2019 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/sh.l b/bin/sh.l index 9664b009..8f0f7723 100644 --- a/bin/sh.l +++ b/bin/sh.l @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 C. McEnroe <june@causal.agency> +/* Copyright (C) 2021 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -36,7 +36,7 @@ static int pop(void) { } %} -%s Param Command Arith Backtick +%s Param Command Arith Backtick Subshell %x DQuote HereDocDel HereDoc HereDocLit word [[:alnum:]_.-]+ @@ -51,7 +51,7 @@ reserved [!{}]|else|do|elif|for|done|fi|then|until|while|if|case|esac "\\". { return Escape; } -<INITIAL,DQuote,HereDoc,Param,Command,Arith>{ +<INITIAL,DQuote,HereDoc,Param,Command,Arith,Subshell>{ "$"[*@#?$!0-9-] | "$"[_[:alpha:][_[:alnum:]]* | "${"[#]?{param}"}" { @@ -73,6 +73,10 @@ reserved [!{}]|else|do|elif|for|done|fi|then|until|while|if|case|esac BEGIN(push(Backtick)); return Subst; } + "(" { + BEGIN(push(Subshell)); + return Normal; + } } <Param>"}" | <Command>")" | @@ -81,6 +85,10 @@ reserved [!{}]|else|do|elif|for|done|fi|then|until|while|if|case|esac BEGIN(pop()); return Subst; } +<Subshell>")" { + BEGIN(pop()); + return Normal; +} "\n" { first = true; diff --git a/bin/shotty.l b/bin/shotty.l index ff78d241..dcac43ec 100644 --- a/bin/shotty.l +++ b/bin/shotty.l @@ -1,4 +1,4 @@ -/* Copyright (C) 2019, 2021 C. McEnroe <june@causal.agency> +/* Copyright (C) 2019, 2021 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -181,13 +181,13 @@ ESC \x1B | (wchar_t)(yytext[1] & 0x3F); return Data; } -[\xE0-\xEF][\x80-\xBF]{2} { +[\xE0-\xEF]([\x80-\xBF]{2}) { ch = (wchar_t)(yytext[0] & 0x0F) << 12 | (wchar_t)(yytext[1] & 0x3F) << 6 | (wchar_t)(yytext[2] & 0x3F); return Data; } -[\xF0-\xF7][\x80-\xBF]{3} { +[\xF0-\xF7]([\x80-\xBF]{3}) { ch = (wchar_t)(yytext[0] & 0x07) << 18 | (wchar_t)(yytext[1] & 0x3F) << 12 | (wchar_t)(yytext[2] & 0x3F) << 6 diff --git a/bin/title.c b/bin/title.c index 82f89d95..47ff720a 100644 --- a/bin/title.c +++ b/bin/title.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 C. McEnroe <june@causal.agency> +/* Copyright (C) 2019 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/bin/up.sh b/bin/up.sh index cebc29c4..6305b1ee 100644 --- a/bin/up.sh +++ b/bin/up.sh @@ -4,21 +4,32 @@ set -eu readonly Host='temp.causal.agency' readonly Root='/var/www' +temp= +temp() { + temp=$(mktemp -d) + trap 'rm -r "$temp"' EXIT +} + +warn= upload() { src=$1 ext=${src##*.} - ts=$(date +'%s') - rand=$(openssl rand -hex 4) - url=$(printf '%s/%x%s.%s' "$Host" "$ts" "$rand" "$ext") + name=$(printf '%x%s' "$(date +%s)" "$(openssl rand -hex 4)") + url="${Host}/${name}.${ext}" scp -q "$src" "${Host}:${Root}/${url}" + if test -n "$warn"; then + test -n "$temp" || temp + cat >"${temp}/warn.html" <<-EOF + <!DOCTYPE html> + <title>${warn}</title> + <meta http-equiv="refresh" content="0;url=${name}.${ext}"> + EOF + url="${Host}/${name}.html" + scp -q "${temp}/warn.html" "${Host}:${Root}/${url}" + fi echo "https://${url}" } -temp() { - temp=$(mktemp -d) - trap 'rm -r "$temp"' EXIT -} - uploadText() { temp cat >"${temp}/input.txt" @@ -64,12 +75,13 @@ uploadTerminal() { upload "${temp}/term.html" } -while getopts 'chst' opt; do +while getopts 'chstw:' opt; do case $opt in (c) fn=uploadCommand;; (h) fn=uploadHilex;; (s) fn=uploadScreen;; (t) fn=uploadTerminal;; + (w) warn=$OPTARG;; (?) exit 1;; esac done diff --git a/bin/when.y b/bin/when.y index 64859da7..46651ebb 100644 --- a/bin/when.y +++ b/bin/when.y @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 June McEnroe <june@causal.agency> +/* Copyright (C) 2019, 2022 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -18,6 +18,9 @@ #include <ctype.h> #include <err.h> +#include <errno.h> +#include <limits.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <strings.h> @@ -30,12 +33,13 @@ static int yylex(void); #define YYSTYPE struct tm static const char *Days[7] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday", }; static const char *Months[12] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December", }; static const struct tm Week = { .tm_mday = 7 }; @@ -117,7 +121,10 @@ static struct tm dateDiff(struct tm a, struct tm b) { .tm_mon = a.tm_mon - b.tm_mon, .tm_mday = a.tm_mday - b.tm_mday, }; - if (a.tm_mon < b.tm_mon) { + if ( + a.tm_mon < b.tm_mon || + (a.tm_mon == b.tm_mon && a.tm_mday < b.tm_mday) + ) { diff.tm_year--; diff.tm_mon += 12; } @@ -130,15 +137,50 @@ static struct tm dateDiff(struct tm a, struct tm b) { return diff; } +static struct { + size_t cap, len; + struct tm *ptr; +} dates; + +static struct tm getDate(const char *name) { + for (size_t i = 0; i < dates.len; ++i) { + if (!strcmp(dates.ptr[i].tm_zone, name)) return dates.ptr[i]; + } + return (struct tm) {0}; +} + +static void setDate(const char *name, struct tm date) { + for (size_t i = 0; i < dates.len; ++i) { + if (strcmp(dates.ptr[i].tm_zone, name)) continue; + char *tm_zone = dates.ptr[i].tm_zone; + dates.ptr[i] = date; + dates.ptr[i].tm_zone = tm_zone; + return; + } + if (dates.len == dates.cap) { + dates.cap = (dates.cap ? dates.cap * 2 : 8); + dates.ptr = realloc(dates.ptr, sizeof(*dates.ptr) * dates.cap); + if (!dates.ptr) err(EX_OSERR, "realloc"); + } + dates.ptr[dates.len] = date; + dates.ptr[dates.len].tm_zone = strdup(name); + if (!dates.ptr[dates.len].tm_zone) err(EX_OSERR, "strdup"); + dates.len++; +} + +static bool silent; + static void printDate(struct tm date) { + if (silent) return; printf( - "%s %s %d %d\n", + "%.3s %.3s %d %d\n", Days[date.tm_wday], Months[date.tm_mon], date.tm_mday, 1900 + date.tm_year ); } static void printScalar(struct tm scalar) { + if (silent) return; if (scalar.tm_year) printf("%dy ", scalar.tm_year); if (scalar.tm_mon) printf("%dm ", scalar.tm_mon); if (scalar.tm_mday % 7) { @@ -161,9 +203,9 @@ static void printScalar(struct tm scalar) { %} -%token Number Month Day +%token Name Number Month Day %left '+' '-' -%right '<' '>' +%right '=' '<' '>' %% @@ -174,6 +216,8 @@ expr: date: dateLit + | Name { $$ = getDate($1.tm_zone); free($1.tm_zone); } + | Name '=' date { setDate($1.tm_zone, $3); free($1.tm_zone); $$ = $3; } | '(' date ')' { $$ = $2; } | '<' date { $$ = dateSub($2, Week); } | '>' date { $$ = dateAdd($2, Week); } @@ -223,35 +267,77 @@ static int yylex(void) { return Number; } - for (int i = 0; i < 7; ++i) { - if (strncasecmp(input, Days[i], 3)) continue; - while (isalpha(*input)) input++; - yylval.tm_wday = i; - return Day; + size_t len; + for (len = 0; isalnum(input[len]) || input[len] == '_'; ++len); + + if (len >= 3) { + for (int i = 0; i < 7; ++i) { + if (strncasecmp(input, Days[i], len)) continue; + yylval.tm_wday = i; + input += len; + return Day; + } + + for (int i = 0; i < 12; ++i) { + if (strncasecmp(input, Months[i], len)) continue; + yylval.tm_mon = i; + input += len; + return Month; + } } - for (int i = 0; i < 12; ++i) { - if (strncasecmp(input, Months[i], 3)) continue; - while (isalpha(*input)) input++; - yylval.tm_mon = i; - return Month; + if (len && (len != 1 || !strchr("dwmy", *input))) { + yylval.tm_zone = strndup(input, len); + if (!yylval.tm_zone) err(EX_OSERR, "strndup"); + input += len; + return Name; } return *input++; } int main(int argc, char *argv[]) { + size_t cap = 0; + char *line = NULL; + + char path[PATH_MAX]; + const char *configHome = getenv("XDG_CONFIG_HOME"); + if (configHome) { + snprintf(path, sizeof(path), "%s/when/dates", configHome); + } else { + snprintf(path, sizeof(path), "%s/.config/when/dates", getenv("HOME")); + } + + FILE *file = fopen(path, "r"); + if (file) { + silent = true; + while (0 < getline(&line, &cap, file)) { + input = line; + yyparse(); + } + fclose(file); + silent = false; + } else if (errno != ENOENT) { + err(EX_CONFIG, "%s", path); + } + if (argc > 1) { - input = argv[1]; - return yyparse(); + if (strcmp(argv[1], "-")) { + input = argv[1]; + return yyparse(); + } else { + for (size_t i = 0; i < dates.len; ++i) { + printf("%s: ", dates.ptr[i].tm_zone); + printScalar(dateDiff(today(), dates.ptr[i])); + } + return EX_OK; + } } struct tm date = today(); printDate(date); printf("\n"); - char *line = NULL; - size_t cap = 0; while (0 < getline(&line, &cap, stdin)) { if (line[0] == '\n') continue; diff --git a/bin/xx.c b/bin/xx.c index 6d04f2f5..39d7ec07 100644 --- a/bin/xx.c +++ b/bin/xx.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 C. McEnroe <june@causal.agency> +/* Copyright (C) 2017 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/doc/pdf/.gitignore b/doc/pdf/.gitignore deleted file mode 100644 index a1363379..00000000 --- a/doc/pdf/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.pdf diff --git a/doc/pdf/Makefile b/doc/pdf/Makefile deleted file mode 100644 index 7afbdcf2..00000000 --- a/doc/pdf/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -PDFS += abi.pdf -PDFS += c11.pdf -PDFS += elf.pdf -PDFS += intel-64-opt.pdf -PDFS += intel-64-sdm-vol-1.pdf -PDFS += intel-64-sdm-vol-2.pdf -PDFS += intel-64-sdm-vol-3.pdf -PDFS += intel-64-sdm-vol-4.pdf -PDFS += multiboot.pdf - -ELF = https://refspecs.linuxbase.org/elf -INTEL = https://software.intel.com/sites/default/files/managed - -URL.abi.pdf = ${ELF}/x86_64-abi-0.99.pdf -URL.c11.pdf = http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf -URL.elf.pdf = ${ELF}/elf.pdf -URL.intel-64-opt.pdf = ${INTEL}/9e/bc/64-ia-32-architectures-optimization-manual.pdf -URL.intel-64-sdm-vol-1.pdf = ${INTEL}/a4/60/253665-sdm-vol-1.pdf -URL.intel-64-sdm-vol-2.pdf = ${INTEL}/a4/60/325383-sdm-vol-2abcd.pdf -URL.intel-64-sdm-vol-3.pdf = ${INTEL}/a4/60/325384-sdm-vol-3abcd.pdf -URL.intel-64-sdm-vol-4.pdf = ${INTEL}/22/0d/335592-sdm-vol-4.pdf -URL.multiboot.pdf = https://www.gnu.org/software/grub/manual/multiboot/multiboot.pdf - -all: ${PDFS} - -${PDFS}: - curl -Lf -o $@ ${URL.$@} - chmod a-w $@ - -clean: - rm -f ${PDFS} diff --git a/doc/zlib/adler32.3 b/doc/zlib/adler32.3 index d713d952..c58a34e7 100644 --- a/doc/zlib/adler32.3 +++ b/doc/zlib/adler32.3 @@ -58,7 +58,7 @@ if (adler != original_adler) error(); This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/adler32_combine.3 b/doc/zlib/adler32_combine.3 index 861f235b..55e801e9 100644 --- a/doc/zlib/adler32_combine.3 +++ b/doc/zlib/adler32_combine.3 @@ -56,7 +56,7 @@ the result has no meaning or utility. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/compress.3 b/doc/zlib/compress.3 index 22b229ee..16445e2f 100644 --- a/doc/zlib/compress.3 +++ b/doc/zlib/compress.3 @@ -77,7 +77,7 @@ parameter is invalid. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/compressBound.3 b/doc/zlib/compressBound.3 index 5800e2ba..d61891eb 100644 --- a/doc/zlib/compressBound.3 +++ b/doc/zlib/compressBound.3 @@ -37,7 +37,7 @@ call to allocate the destination buffer. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/crc32.3 b/doc/zlib/crc32.3 index 3c9cc8c4..a42df2af 100644 --- a/doc/zlib/crc32.3 +++ b/doc/zlib/crc32.3 @@ -59,7 +59,7 @@ if (crc != original_crc) error(); This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/crc32_combine.3 b/doc/zlib/crc32_combine.3 index 2f79f623..b25da679 100644 --- a/doc/zlib/crc32_combine.3 +++ b/doc/zlib/crc32_combine.3 @@ -47,7 +47,7 @@ and This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/deflate.3 b/doc/zlib/deflate.3 index 7df313ee..be182d96 100644 --- a/doc/zlib/deflate.3 +++ b/doc/zlib/deflate.3 @@ -363,7 +363,7 @@ to continue compressing. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/deflateBound.3 b/doc/zlib/deflateBound.3 index 63e80246..be97494c 100644 --- a/doc/zlib/deflateBound.3 +++ b/doc/zlib/deflateBound.3 @@ -64,7 +64,7 @@ are used. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/deflateCopy.3 b/doc/zlib/deflateCopy.3 index f30d6301..f20e0a9e 100644 --- a/doc/zlib/deflateCopy.3 +++ b/doc/zlib/deflateCopy.3 @@ -59,7 +59,7 @@ in both source and destination. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/deflateEnd.3 b/doc/zlib/deflateEnd.3 index e24259a3..0abaabe1 100644 --- a/doc/zlib/deflateEnd.3 +++ b/doc/zlib/deflateEnd.3 @@ -43,7 +43,7 @@ may be set but then points to a static string This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/deflateGetDictionary.3 b/doc/zlib/deflateGetDictionary.3 index 403f6d10..b9dabfe2 100644 --- a/doc/zlib/deflateGetDictionary.3 +++ b/doc/zlib/deflateGetDictionary.3 @@ -72,7 +72,7 @@ if the stream state is inconsistent. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/deflateInit.3 b/doc/zlib/deflateInit.3 index a893dd91..52179883 100644 --- a/doc/zlib/deflateInit.3 +++ b/doc/zlib/deflateInit.3 @@ -171,7 +171,7 @@ if there is no error message. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/deflateInit2.3 b/doc/zlib/deflateInit2.3 index 6a581ef8..a7d68b99 100644 --- a/doc/zlib/deflateInit2.3 +++ b/doc/zlib/deflateInit2.3 @@ -220,7 +220,7 @@ is set to null if there is no error message. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/deflateParams.3 b/doc/zlib/deflateParams.3 index 8e770d4e..9eb5ca16 100644 --- a/doc/zlib/deflateParams.3 +++ b/doc/zlib/deflateParams.3 @@ -116,7 +116,7 @@ with more output space. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/deflatePending.3 b/doc/zlib/deflatePending.3 index 1ce40fc2..35fa6d38 100644 --- a/doc/zlib/deflatePending.3 +++ b/doc/zlib/deflatePending.3 @@ -49,7 +49,7 @@ if the source stream state was inconsistent. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/deflatePrime.3 b/doc/zlib/deflatePrime.3 index 639e715a..10a2924b 100644 --- a/doc/zlib/deflatePrime.3 +++ b/doc/zlib/deflatePrime.3 @@ -57,7 +57,7 @@ if the source stream state was inconsistent. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/deflateReset.3 b/doc/zlib/deflateReset.3 index 7309ac15..1a18c507 100644 --- a/doc/zlib/deflateReset.3 +++ b/doc/zlib/deflateReset.3 @@ -50,7 +50,7 @@ being This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/deflateSetDictionary.3 b/doc/zlib/deflateSetDictionary.3 index c2c9d7c2..3e66d3cf 100644 --- a/doc/zlib/deflateSetDictionary.3 +++ b/doc/zlib/deflateSetDictionary.3 @@ -135,7 +135,7 @@ for raw deflate This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/deflateSetHeader.3 b/doc/zlib/deflateSetHeader.3 index 6fec645c..03d4f4d3 100644 --- a/doc/zlib/deflateSetHeader.3 +++ b/doc/zlib/deflateSetHeader.3 @@ -173,7 +173,7 @@ if the source stream state was inconsistent. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/deflateTune.3 b/doc/zlib/deflateTune.3 index 7269dec0..ea4dd915 100644 --- a/doc/zlib/deflateTune.3 +++ b/doc/zlib/deflateTune.3 @@ -63,7 +63,7 @@ for an invalid deflate stream. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzbuffer.3 b/doc/zlib/gzbuffer.3 index de7c706a..92438c48 100644 --- a/doc/zlib/gzbuffer.3 +++ b/doc/zlib/gzbuffer.3 @@ -52,7 +52,7 @@ such as being called too late. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzclose.3 b/doc/zlib/gzclose.3 index 77eae11e..bfcc583e 100644 --- a/doc/zlib/gzclose.3 +++ b/doc/zlib/gzclose.3 @@ -90,7 +90,7 @@ on success. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzdirect.3 b/doc/zlib/gzdirect.3 index 8fa26aae..640fd4c5 100644 --- a/doc/zlib/gzdirect.3 +++ b/doc/zlib/gzdirect.3 @@ -78,7 +78,7 @@ which may not be desired. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzeof.3 b/doc/zlib/gzeof.3 index 26c415fe..ba823aa6 100644 --- a/doc/zlib/gzeof.3 +++ b/doc/zlib/gzeof.3 @@ -56,7 +56,7 @@ end of file was detected. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzerror.3 b/doc/zlib/gzerror.3 index 13dcddd4..a9e175fc 100644 --- a/doc/zlib/gzerror.3 +++ b/doc/zlib/gzerror.3 @@ -68,7 +68,7 @@ that is being written concurrently. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzflush.3 b/doc/zlib/gzflush.3 index b93c03e7..476f7c09 100644 --- a/doc/zlib/gzflush.3 +++ b/doc/zlib/gzflush.3 @@ -66,7 +66,7 @@ see function This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzfread.3 b/doc/zlib/gzfread.3 index 66231cc3..7bf57fc5 100644 --- a/doc/zlib/gzfread.3 +++ b/doc/zlib/gzfread.3 @@ -100,7 +100,7 @@ and the error state is set to This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzfwrite.3 b/doc/zlib/gzfwrite.3 index 38383a33..6835db3a 100644 --- a/doc/zlib/gzfwrite.3 +++ b/doc/zlib/gzfwrite.3 @@ -68,7 +68,7 @@ and the error state is set to This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzgetc.3 b/doc/zlib/gzgetc.3 index 93a90edd..db9143ec 100644 --- a/doc/zlib/gzgetc.3 +++ b/doc/zlib/gzgetc.3 @@ -48,7 +48,7 @@ or error. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzgets.3 b/doc/zlib/gzgets.3 index 2a329e9e..c1435b39 100644 --- a/doc/zlib/gzgets.3 +++ b/doc/zlib/gzgets.3 @@ -60,7 +60,7 @@ are indeterminate. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzoffset.3 b/doc/zlib/gzoffset.3 index cbb78a77..b03c557e 100644 --- a/doc/zlib/gzoffset.3 +++ b/doc/zlib/gzoffset.3 @@ -44,7 +44,7 @@ returns -1. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzopen.3 b/doc/zlib/gzopen.3 index e3cb4cbd..9da647e1 100644 --- a/doc/zlib/gzopen.3 +++ b/doc/zlib/gzopen.3 @@ -254,7 +254,7 @@ for the routine This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzprintf.3 b/doc/zlib/gzprintf.3 index 26961f34..a2a241a2 100644 --- a/doc/zlib/gzprintf.3 +++ b/doc/zlib/gzprintf.3 @@ -64,7 +64,7 @@ This can be determined using This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzputc.3 b/doc/zlib/gzputc.3 index 161e5631..66897b5e 100644 --- a/doc/zlib/gzputc.3 +++ b/doc/zlib/gzputc.3 @@ -36,7 +36,7 @@ or -1 in case of error. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzputs.3 b/doc/zlib/gzputs.3 index f5d1fd84..71833ab2 100644 --- a/doc/zlib/gzputs.3 +++ b/doc/zlib/gzputs.3 @@ -34,7 +34,7 @@ or -1 in case of error. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzread.3 b/doc/zlib/gzread.3 index 84439eaa..4118eca7 100644 --- a/doc/zlib/gzread.3 +++ b/doc/zlib/gzread.3 @@ -108,7 +108,7 @@ and the error state is set to This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzseek.3 b/doc/zlib/gzseek.3 index cd85fd4c..a14b2db6 100644 --- a/doc/zlib/gzseek.3 +++ b/doc/zlib/gzseek.3 @@ -101,7 +101,7 @@ would be before the current position. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzsetparams.3 b/doc/zlib/gzsetparams.3 index ff544d23..f6ff9ed7 100644 --- a/doc/zlib/gzsetparams.3 +++ b/doc/zlib/gzsetparams.3 @@ -44,7 +44,7 @@ if there is a memory allocation error. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzungetc.3 b/doc/zlib/gzungetc.3 index 90cdafc7..fbe9371c 100644 --- a/doc/zlib/gzungetc.3 +++ b/doc/zlib/gzungetc.3 @@ -60,7 +60,7 @@ or -1 on failure. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/gzwrite.3 b/doc/zlib/gzwrite.3 index 606d89f4..73407ef5 100644 --- a/doc/zlib/gzwrite.3 +++ b/doc/zlib/gzwrite.3 @@ -32,7 +32,7 @@ or 0 in case of error. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/inflate.3 b/doc/zlib/inflate.3 index ca90c270..255e0f84 100644 --- a/doc/zlib/inflate.3 +++ b/doc/zlib/inflate.3 @@ -391,7 +391,7 @@ is to be attempted. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/inflateBack.3 b/doc/zlib/inflateBack.3 index 59d5f8cb..fcda7452 100644 --- a/doc/zlib/inflateBack.3 +++ b/doc/zlib/inflateBack.3 @@ -278,7 +278,7 @@ cannot return This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/inflateBackEnd.3 b/doc/zlib/inflateBackEnd.3 index eeb88636..39fbea8f 100644 --- a/doc/zlib/inflateBackEnd.3 +++ b/doc/zlib/inflateBackEnd.3 @@ -36,7 +36,7 @@ if the stream state was inconsistent. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/inflateBackInit.3 b/doc/zlib/inflateBackInit.3 index 483edda5..d029542e 100644 --- a/doc/zlib/inflateBackInit.3 +++ b/doc/zlib/inflateBackInit.3 @@ -77,7 +77,7 @@ does not match the version of the header file. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/inflateCopy.3 b/doc/zlib/inflateCopy.3 index 53b30edf..167b879b 100644 --- a/doc/zlib/inflateCopy.3 +++ b/doc/zlib/inflateCopy.3 @@ -52,7 +52,7 @@ in both source and destination. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/inflateEnd.3 b/doc/zlib/inflateEnd.3 index 9b18226b..54945b50 100644 --- a/doc/zlib/inflateEnd.3 +++ b/doc/zlib/inflateEnd.3 @@ -37,7 +37,7 @@ if the stream state was inconsistent. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/inflateGetDictionary.3 b/doc/zlib/inflateGetDictionary.3 index e70ee736..9290850c 100644 --- a/doc/zlib/inflateGetDictionary.3 +++ b/doc/zlib/inflateGetDictionary.3 @@ -62,7 +62,7 @@ if the stream state is inconsistent. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/inflateGetHeader.3 b/doc/zlib/inflateGetHeader.3 index f77670f2..57f7c443 100644 --- a/doc/zlib/inflateGetHeader.3 +++ b/doc/zlib/inflateGetHeader.3 @@ -163,7 +163,7 @@ if the source stream state was inconsistent. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/inflateInit.3 b/doc/zlib/inflateInit.3 index 186b058a..66a1d4f7 100644 --- a/doc/zlib/inflateInit.3 +++ b/doc/zlib/inflateInit.3 @@ -94,7 +94,7 @@ is set to null if there is no error message. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/inflateInit2.3 b/doc/zlib/inflateInit2.3 index a630f12a..5b8b49ac 100644 --- a/doc/zlib/inflateInit2.3 +++ b/doc/zlib/inflateInit2.3 @@ -174,7 +174,7 @@ is set to null if there is no error message. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/inflateMark.3 b/doc/zlib/inflateMark.3 index 2d15993d..90e2ee0b 100644 --- a/doc/zlib/inflateMark.3 +++ b/doc/zlib/inflateMark.3 @@ -81,7 +81,7 @@ or -65536 if the provided source stream state was inconsistent. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/inflatePrime.3 b/doc/zlib/inflatePrime.3 index c89dc2c5..66953665 100644 --- a/doc/zlib/inflatePrime.3 +++ b/doc/zlib/inflatePrime.3 @@ -66,7 +66,7 @@ if the source stream state was inconsistent. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/inflateReset.3 b/doc/zlib/inflateReset.3 index a8d2e219..53c4ffe2 100644 --- a/doc/zlib/inflateReset.3 +++ b/doc/zlib/inflateReset.3 @@ -74,7 +74,7 @@ parameter is invalid. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/inflateSetDictionary.3 b/doc/zlib/inflateSetDictionary.3 index 0e3c60c7..291c97e8 100644 --- a/doc/zlib/inflateSetDictionary.3 +++ b/doc/zlib/inflateSetDictionary.3 @@ -78,7 +78,7 @@ doesn't match the expected one This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/inflateSync.3 b/doc/zlib/inflateSync.3 index 35264ddd..56d3ca28 100644 --- a/doc/zlib/inflateSync.3 +++ b/doc/zlib/inflateSync.3 @@ -65,7 +65,7 @@ until success or the end of the input data. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/uncompress.3 b/doc/zlib/uncompress.3 index d951da9b..1047ad91 100644 --- a/doc/zlib/uncompress.3 +++ b/doc/zlib/uncompress.3 @@ -85,7 +85,7 @@ with the uncompressed data up to that point. This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/zlibCompileFlags.3 b/doc/zlib/zlibCompileFlags.3 index 465195c2..59cc24a8 100644 --- a/doc/zlib/zlibCompileFlags.3 +++ b/doc/zlib/zlibCompileFlags.3 @@ -156,7 +156,7 @@ not secure! This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/doc/zlib/zlibVersion.3 b/doc/zlib/zlibVersion.3 index 35a9854b..04377527 100644 --- a/doc/zlib/zlibVersion.3 +++ b/doc/zlib/zlibVersion.3 @@ -38,7 +38,7 @@ and This manual page was converted from .In zlib.h to mdoc format by -.An C. McEnroe Aq Mt june@causal.agency . +.An June McEnroe Aq Mt june@causal.agency . . .Sh AUTHORS .An Jean-loup Gailly Aq Mt jloup@gzip.org diff --git a/gpl.c b/gpl.c index 8634449b..8ff4916d 100644 --- a/gpl.c +++ b/gpl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 June McEnroe <june@causal.agency> +/* Copyright (C) 2024 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,4 +17,3 @@ #include <err.h> #include <stdio.h> #include <stdlib.h> -#include <sysexits.h> diff --git a/home/.config/X/resources b/home/.config/X/resources index cfedf60b..f4603cd9 100644 --- a/home/.config/X/resources +++ b/home/.config/X/resources @@ -26,7 +26,7 @@ XTerm*VT100*translations: #override \n\ <Btn4Down>: scroll-back(1,line,m) \n\ <Btn5Down>: scroll-forw(1,line,m) -XTerm*faceName: Go Mono:size=11 +XTerm*faceName: Go Mono:size=12 XTerm*internalBorder: 6 XTerm*colorBDMode: true XTerm*scrollBar: false diff --git a/home/.config/git/config b/home/.config/git/config index 1a6d5ce1..c990de2c 100644 --- a/home/.config/git/config +++ b/home/.config/git/config @@ -2,6 +2,9 @@ name = June McEnroe email = june@causal.agency +[branch] + sort = committerdate + [commit] verbose = true @@ -12,6 +15,9 @@ [merge] conflictStyle = diff3 +[push] + autoSetupRemote = true + [pull] rebase = true @@ -21,5 +27,8 @@ [pretty] log = %Cred%h %Creset%s%C(yellow)%d %Cgreen(%ar) %Cblue<%aN> +[alias] + forgive = blame + [include] path = ./private diff --git a/home/.local/bin/mins b/home/.local/bin/mins new file mode 100755 index 00000000..9cbd5fa8 --- /dev/null +++ b/home/.local/bin/mins @@ -0,0 +1,4 @@ +#!/bin/sh +exec dc <<EOF +$1 60~rn[h]nn[m]p +EOF diff --git a/home/.shrc b/home/.shrc index 1d7542a3..afa87fe5 100644 --- a/home/.shrc +++ b/home/.shrc @@ -25,7 +25,7 @@ man() { for sect in $MANSECT; do command man -w $sect "$1" >/dev/null 2>&1 && exec man $sect "$1" done - exec man "$1") + exec command man "$1") } cd() { @@ -50,15 +50,5 @@ fi export LESS_TERMCAP_us=$(tput sitm) export LESS_TERMCAP_ue=$(tput ritm) -hostname=$(hostname -s) -rprompt() { - local pwd - pwd=${PWD#${HOME}} - [ "${pwd}" != "${PWD}" ] && pwd="~${pwd}" - [ "${TERM%-*}" = 'xterm' ] \ - && printf '\33]0;%s\a' "${SSH_CLIENT:+${hostname}:}${pwd##*/}" >&2 - printf '%s' "${SSH_CLIENT:+${hostname}:}${pwd}" -} -PS1=' -$ ' -RPS1='${?#0} $(rprompt)' +PS1='\[\033]0;${SSH_CLIENT:+\\h:}\W\a\] +${?#0}$ ' diff --git a/home/.ssh/config b/home/.ssh/config index d354a6ea..f579ae9f 100644 --- a/home/.ssh/config +++ b/home/.ssh/config @@ -1,20 +1,17 @@ IgnoreUnknown Include Include config_private +AddKeysToAgent yes SendEnv LANG LC_* -Host monday beastie puffy toaster tux progynova +Host tuesday beastie puffy toaster tux progynova HostName %h.local ForwardAgent yes RemoteForward 7062 127.0.0.1:7062 -Host scout pyro +Host scout soldier pyro demo heavy engi medic sniper spy HostName %h.causal.agency Port 2222 -Host june july - HostName %h.nyc3.do.causal.agency - Port 2222 - Host git.causal.agency temp.causal.agency Port 2222 diff --git a/home/.xsession b/home/.xsession index a51d52f2..1e05126c 100644 --- a/home/.xsession +++ b/home/.xsession @@ -4,8 +4,11 @@ export LC_CTYPE=en_US.UTF-8 xset r rate 175 m 5/4 0 xmodmap ~/.config/X/modmap xrdb -load ~/.config/X/resources -xsetroot -bitmap /usr/X11R6/include/X11/bitmaps/xsnow \ - -bg rgb:14/13/0E -fg rgb:7A/49/55 + +fg=998D6B +command -v scheme && fg=$(scheme -p $(jot -r 1 1 8)) +xsetroot -bitmap /usr/X11R6/include/X11/bitmaps/escherknot \ + -bg '#14130E' -fg "#${fg}" xterm -name clock -geometry 14x1-0+0 -sl 0 -e clock & exec cwm -c ~/.config/cwm/cwmrc diff --git a/install.sh b/install.sh index 1d9b6e6b..11269fb7 100644 --- a/install.sh +++ b/install.sh @@ -33,7 +33,7 @@ Darwin() { packages=$(echo $packages | sed 's/the_silver_searcher/ag/') cd git/jorts git pull - ./Plan git mandoc nvi $packages | sh + ./Install git mandoc nvi $packages } $(uname) diff --git a/txt/books.txt b/txt/books.txt index 88af73b0..7ebae70c 100644 --- a/txt/books.txt +++ b/txt/books.txt @@ -1,5 +1,25 @@ +[ 2023 ] + + 7. ★★☆ Alix E. Harrow, Starling House + 6. ★★☆ Alix E. Harrow, A Mirror Mended + 5. ★★★ Alix E. Harrow, A Spindle Splintered + 4. ★★☆ Alyson Greaves, The Sisters of Dorley (ch. 1-15) + 3. ★☆☆ Nnedi Okorafor, Noor + 2. ★★☆ Nnedi Okorafor, Remote Control + 1. ★★☆ Becky Chambers, A Prayer for the Crown-Shy + [ 2022 ] + 15. ★★★ Becky Chambers, The Long Way To a Small Angry Planet + 14. ★★★ ed. Tristan Taormino, Take Me There + 13. ★★★★ Becky Chambers, A Closed and Common Orbit + 12. ★★☆ Sybil Lamb, I've Got a Time Bomb + 11. ☆☆☆ Ruth Ozeki, The Book of Form and Emptiness + 10. ★☆☆ Sally Rooney, Conversations With Friends + 9. ★☆☆ Sally Rooney, Normal People + 8. ★★★ Andrea Stewart, The Bone Shard Emperor + 7. ★★☆ ed. Gwen Benaway, Maiden, Mother, Crone + 6. ★★★ Andrea Stewart, The Bone Shard Daughter 5. ★☆☆ Madeline Miller, Circe 4. ★★★ Natalie Zina Walschots, Hench 3. ★★★ V. E. Schwab, The Invisible Life of Addie LaRue diff --git a/txt/shows.txt b/txt/shows.txt index 62e6a071..2abacf5b 100644 --- a/txt/shows.txt +++ b/txt/shows.txt @@ -1,3 +1,5 @@ +2022-12-18 (SAT) LINGUA IGNOTA +2022-06-04 (MAI) Honeydrip, MAGELLA, BACKXWASH 2020-01-23 (La Sala Rossa) Secondsight, BIG|BRAVE 2019-12-10 (Casa del Popolo) meth, Street Sects 2019-06-22 (Casa del Popolo) Persons Unknown, Palissade, Police des Moeurs, Blu Anxiety diff --git a/txt/tweets.txt b/txt/tweets.txt deleted file mode 100644 index 240351ec..00000000 --- a/txt/tweets.txt +++ /dev/null @@ -1,32 +0,0 @@ -triangle forum -https://twitter.com/g0m/status/963890156477603841 - -damn ya ass fat what's ya pronouns? -https://twitter.com/msbigmilk/status/1291218055939448833 - -afab -https://twitter.com/ErisGael/status/1257524779046907904 - -chaos emeralds -https://twitter.com/ErisGael/status/1190147736244490240 - -might as well salivate -https://twitter.com/prawn_meat/status/857444039833944064 - -notifications -https://twitter.com/WTMMP/status/1259694226595610629 - -all robot & computers -https://twitter.com/cryptcrier/status/1238339418160680960 - -the wet world -https://twitter.com/TragicAllyHere/status/1137187876507140098 - -a purchase? -https://twitter.com/pant_leg/status/1027693563604230144 - -influencer -https://twitter.com/witchpuppy/status/974690828257054721 - --Wint-conversion -https://twitter.com/jckarter/status/967802665080995840 diff --git a/www/causal.agency/.gitignore b/www/causal.agency/.gitignore index 7935a3c1..b00b1c3c 100644 --- a/www/causal.agency/.gitignore +++ b/www/causal.agency/.gitignore @@ -1,3 +1,4 @@ -*.html +index.html +leveler.html scheme.css scheme.png diff --git a/www/causal.agency/Makefile b/www/causal.agency/Makefile index 75849db0..8c74f8f1 100644 --- a/www/causal.agency/Makefile +++ b/www/causal.agency/Makefile @@ -1,11 +1,14 @@ WEBROOT = /var/www/causal.agency -FILES = index.html style.css scheme.css scheme.png +GEN = index.html scheme.css scheme.png +FILES = ${GEN} style.css alpha.html lands.html all: ${FILES} -index.html: index.7 - mandoc -T html -O style=style.css index.7 > index.html +.SUFFIXES: .7 .html + +.7.html: + mandoc -T html -O style=style.css $< > $@ scheme.css: scheme -st > scheme.css @@ -17,4 +20,4 @@ install: ${FILES} install -C -m 644 ${FILES} ${WEBROOT} clean: - rm -f index.html scheme.css scheme.png + rm -f ${GEN} diff --git a/www/causal.agency/alpha.html b/www/causal.agency/alpha.html new file mode 100644 index 00000000..0d83f530 --- /dev/null +++ b/www/causal.agency/alpha.html @@ -0,0 +1,92 @@ +<!DOCTYPE html> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> +<title>all 26 letters of the alphabet RANKED</title> +<style> +body, button { font-size: 200%; text-align: center; } +button { margin: 1em; padding: 1ch; } +button#shuffle { font-size: 100%; } +</style> + +which letter do you like more? +<p> +<button id="a">A</button> +<button id="b">B</button> +<p> +<details> +<summary>current ranking</summary> +<p> +<span id="ranking">ABCDEFGHIJKLMNOPQRSTUVWXYZ</span> +<p> +<button id="shuffle">reshuffle</button> +</details> + +<script> +let buttonA = document.getElementById("a"); +let buttonB = document.getElementById("b"); +let ranking = document.getElementById("ranking"); + +let alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""); +let rand = (bound) => Math.floor(Math.random() * bound); +function shuffle() { + for (let i = alpha.length - 1; i > 0; --i) { + let j = rand(i + 1); + let x = alpha[i]; + alpha[i] = alpha[j]; + alpha[j] = x; + } +} +if (localStorage.getItem("alpha")) { + alpha = localStorage.getItem("alpha").split(""); +} else { + shuffle(); +} + +let index = 0; +let even = true; +function choose(o) { + if (o == "b") { + let x = alpha[index]; + alpha[index] = alpha[index + 1]; + alpha[index + 1] = x; + } + index += 2; + if (index > alpha.length - 2) { + even = !even; + index = (even ? 0 : 1); + } + update(); +} + +document.onkeydown = function(event) { + if (event.key.toUpperCase() == alpha[index]) { + choose("a"); + } else if (event.key.toUpperCase() == alpha[index + 1]) { + choose("b"); + } +} + +function update() { + localStorage.setItem("alpha", alpha.join("")); + ranking.innerText = alpha.join(""); + let a = buttonA; + let b = buttonB; + if (rand(2)) { + a = buttonB; + b = buttonA; + } + let lc = (c) => c; + if (rand(2)) lc = (c) => c.toLowerCase(); + a.innerText = lc(alpha[index]); + b.innerText = lc(alpha[index + 1]); + a.onclick = () => choose("a"); + b.onclick = () => choose("b"); +} +update(); + +document.getElementById("shuffle").onclick = function() { + if (confirm("Are you SURE you want to throw away all your hard work?")) { + shuffle(); + update(); + } +} +</script> diff --git a/www/causal.agency/index.7 b/www/causal.agency/index.7 index c270f477..1e019574 100644 --- a/www/causal.agency/index.7 +++ b/www/causal.agency/index.7 @@ -1,10 +1,10 @@ -.Dd November 3, 2021 +.Dd April 18, 2024 .Dt CAUSAL.AGENCY 7 .Os "Causal Agency" . .Sh NAME .Nm june -.Nd computer enthusiast (her) +.Nd computer enthusiast (she/her) . .Sh SYNOPSIS .Nm mail @@ -29,6 +29,8 @@ and experience more magic. \(em .Lk https://text.causal.agency words \(em +.Lk https://photo.causal.agency photos +\(em .Lk /list/ mailist . .Pp @@ -42,7 +44,7 @@ a cosy IRC client a full-text search IRC logger .It Lk https://git.causal.agency/scooper/about scooper a web interface for litterbox -.It Lk https://git.causal.agency/catsit/about catsit +.It Lk https://git.causal.agency/kitd/about kitd a process supervisor .It Lk https://git.causal.agency/imbox/about "imbox & git-fetch-email" a tool to pull patches out of IMAP @@ -64,4 +66,11 @@ an earthy terminal colour scheme .El . .Sh SEE ALSO +.Bl -bullet +.It .Lk /bin/ bin +.It +.Lk lands.html "Magic lands quiz" +.It +.Lk alpha.html "alphabet ranking game" +.El diff --git a/www/causal.agency/lands.html b/www/causal.agency/lands.html new file mode 100644 index 00000000..7aaadd80 --- /dev/null +++ b/www/causal.agency/lands.html @@ -0,0 +1,176 @@ +<!DOCTYPE html> +<title>Lands Quiz</title> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> +<style> +html { font: 14pt sans-serif; line-height: 1.5em; } +body { padding: 1em 1ch; max-width: 78ch; margin: auto; } +h1 { text-align: center; } +h2 { margin-top: 0; } +button { font-size: 100%; padding: 0.5em 1ch; } +img { max-width: 100%; } +div.cols { display: grid; grid-template-columns: 1fr 1fr; gap: 2ch; } +</style> + +<h1 id="loading">Loading...</h1> +<h1 id="error" hidden>Failed to load cards :(</h1> + +<div id="game" hidden> +<h1>Magic Lands Quiz</h1> +<p>Try to guess the colours of mana each land produces!</p> +<div class="cols"> + <div> + <img id="back" src="https://backs.scryfall.io/normal/0/a/0aeebaf5-8c7d-4636-9e82-8c27447861f7.jpg"> + <a id="link" target="_blank"> + <img id="image1" hidden> + <img id="image2" hidden> + </a> + </div> + <div> + <h2 id="name"></h2> + <input type="checkbox" id="w"> <label for="w">White</label><br> + <input type="checkbox" id="u"> <label for="u">Blue</label><br> + <input type="checkbox" id="b"> <label for="b">Black</label><br> + <input type="checkbox" id="r"> <label for="r">Red</label><br> + <input type="checkbox" id="g"> <label for="g">Green</label><br> + <p><button id="submit">Submit</button></p> + <h3>Score: <span id="score">0</span>/<span id="total">0</span></h3> + </div> +</div> +</div> + +<script> +function shuffle(arr) { + let rand = (bound) => Math.floor(Math.random() * bound); + for (let i = arr.length-1; i > 0; --i) { + let j = rand(i+1); + let x = arr[i]; + arr[i] = arr[j]; + arr[j] = x; + } +} + +const CardBack = +"https://backs.scryfall.io/normal/0/a/0aeebaf5-8c7d-4636-9e82-8c27447861f7.jpg"; + +function hideCard() { + document.getElementById("back").hidden = false; + document.getElementById("image1").hidden = true; + document.getElementById("image2").hidden = true; +} + +function showCard(card) { + document.getElementById("back").hidden = true; + document.getElementById("link").href = card.scryfall_uri; + let image1 = document.getElementById("image1"); + let image2 = document.getElementById("image2"); + if (card.card_faces) { + image1.src = card.card_faces[0].image_uris.normal; + image2.src = card.card_faces[1].image_uris.normal; + image1.hidden = false; + image2.hidden = false; + } else { + image1.src = card.image_uris.normal; + image1.hidden = false; + } +} + +function resetChecks() { + for (let c of "wubrg") { + let input = document.getElementById(c); + input.checked = false; + input.disabled = false; + input.labels[0].style.fontWeight = "normal"; + } +} + +function checkChecks(card) { + let score = 0; + let total = 0; + let checked = 0; + for (let c of "wubrg") { + let input = document.getElementById(c); + let produced = card.produced_mana.includes(c.toUpperCase()); + if (produced) { + total++; + input.labels[0].style.fontWeight = "bold"; + if (input.checked) score++; + } + if (input.checked) checked++; + input.disabled = true; + } + if (checked > total) score -= (checked - total); + if (score < 0) score = 0; + return { score: score, total: total }; +} + +document.onkeydown = function(event) { + for (let c of "wubrg") { + if (event.key == c) { + let input = document.getElementById(c); + if (!input.disabled) input.checked ^= true; + } + } + if (event.key == "Enter") { + document.getElementById("submit").click(); + } +} + +let score = 0; +let total = 0; +let cards = []; +let card = null; + +function nextCard() { + hideCard(); + resetChecks(); + card = cards.shift(); + document.getElementById("name").innerText = card.name; +} + +document.getElementById("submit").onclick = function() { + if (card) { + let { score: cardScore, total: cardTotal } = checkChecks(card); + total += cardTotal; + score += cardScore; + document.getElementById("score").innerText = score; + document.getElementById("total").innerText = total; + showCard(card); + card = null; + if (cards.length) { + this.innerText = "Next card"; + } else { + this.disabled = true; + this.innerText = "No more cards"; + } + } else { + nextCard(); + this.innerText = "Submit"; + } +} + +function loadCards(resp) { + let loading = document.getElementById("loading"); + let error = document.getElementById("error"); + let game = document.getElementById("game"); + if (resp.status != 200) { + loading.hidden = true; + error.hidden = false; + } + resp.json().then((json) => { + cards.push(...json.data); + if (json.has_more) { + setTimeout(() => fetch(json.next_page).then(loadCards), 50); + } else { + loading.hidden = true; + game.hidden = false; + shuffle(cards); + nextCard(); + } + }); +} + +const Search = +"https://api.scryfall.com/cards/search?q=t:land+id>=2+produces>=2+produces!=wubrg"; +fetch(Search).then(loadCards); + +</script> diff --git a/www/causal.agency/style.css b/www/causal.agency/style.css index 368d8da1..265c62c2 100644 --- a/www/causal.agency/style.css +++ b/www/causal.agency/style.css @@ -11,6 +11,11 @@ dl.Bl-diag > dt { font-weight: bold; } code.Nm, code.Fl, code.Cm, code.Ic, code.In, code.Fd, code.Fn, code.Cd { font-weight: bold; font-family: inherit; } +div.head, div.foot { display: flex; justify-content: space-between; } +.head-ltitle, .foot-date { flex: 1; } +.head-vol { flex: 0 1 auto; text-align: center; } +.head-rtitle, .foot-os { flex: 1; text-align: right; } + html { font-family: monospace; line-height: 1.25em; } body { max-width: 80ch; margin: 1em auto; padding: 0 1ch; } table { border-collapse: collapse; } diff --git a/www/git.causal.agency/.gitignore b/www/git.causal.agency/.gitignore index 25e26cc8..eaed8039 100644 --- a/www/git.causal.agency/.gitignore +++ b/www/git.causal.agency/.gitignore @@ -1,3 +1,4 @@ +*.html about-filter compress ctags diff --git a/www/git.causal.agency/Makefile b/www/git.causal.agency/Makefile index f05d4a4a..86b9f3eb 100644 --- a/www/git.causal.agency/Makefile +++ b/www/git.causal.agency/Makefile @@ -2,6 +2,7 @@ PREFIX = /var/www CONFDIR = ${PREFIX}/conf DATADIR = ${PREFIX}/cgit BINDIR = ${PREFIX}/bin +WEBROOT = ${PREIFX}/git.causal.agency CFLAGS += -Wall -Wextra LDFLAGS = -static -pie @@ -17,7 +18,9 @@ BINS += mtags BINS += owner-filter BINS += source-filter -all: ${BINS} +HTMLS = index.html + +all: ${BINS} ${HTMLS} compress ctags mandoc: ${MAKE} -C /usr/src/usr.bin/$@ LDFLAGS='${LDFLAGS}' @@ -35,12 +38,16 @@ hilex htagml mtags: about-filter email-filter owner-filter source-filter: filter ln -f filter $@ +index.html: index.7 + mandoc -Thtml -Ostyle=https://causal.agency/style.css index.7 >index.html + install: cgitrc custom.css ${BINS} install -m 644 cgitrc ${CONFDIR} install -m 644 custom.css ${DATADIR} install -d -o www -g daemon ${PREFIX}/cache/cgit install -d -m 1700 -o www -g daemon ${PREFIX}/tmp install -s ${BINS} ${BINDIR} + install -m 644 ${HTMLS} ${WEBROOT} clean: - rm -f compress filter ${BINS} + rm -f compress filter ${BINS} ${HTMLS} diff --git a/www/git.causal.agency/filter.c b/www/git.causal.agency/filter.c index 9ed9ee17..7c7e9320 100644 --- a/www/git.causal.agency/filter.c +++ b/www/git.causal.agency/filter.c @@ -32,12 +32,8 @@ static int email(void) { size_t cap = 0; char *buf = NULL; if (getline(&buf, &cap, stdin) < 0) err(1, "getline"); - long x = 1; - for (char *ch = buf; *ch && *ch != ' '; ++ch) { - x *= *ch; - } - if (buf[0] == 'C' && x == 1251729952200L) { - printf("C.%s", buf + strcspn(buf, " ")); + if (buf[0] == 'C' && !strncmp(&buf[strcspn(buf, " ")], " McEnroe", 8)) { + printf("June%s", &buf[strcspn(buf, " ")]); } else { printf("%s", buf); } @@ -143,6 +139,7 @@ static int source(int argc, char *argv[]) { } int main(int argc, char *argv[]) { +#ifdef __OpenBSD__ int error; switch (getprogname()[0]) { break; case 'a': error = pledge("stdio exec", NULL); @@ -150,6 +147,7 @@ int main(int argc, char *argv[]) { break; default: error = pledge("stdio", NULL); } if (error) err(1, "pledge"); +#endif switch (getprogname()[0]) { case 'a': return about(argc, argv); case 'e': return email(); diff --git a/www/git.causal.agency/index.7 b/www/git.causal.agency/index.7 new file mode 100644 index 00000000..58a40dfe --- /dev/null +++ b/www/git.causal.agency/index.7 @@ -0,0 +1,81 @@ +.Dd January 12, 2024 +.Dt GIT.CAUSAL.AGENCY 7 +.Os "Causal Agency" +. +.Sh NAME +.Nm causal agency +.Nd \(dqI think some people from the Gentoo project are behind this.\(dq +. +.Sh DESCRIPTION +basically cgit (awful software) +getting hammered by web crawlers +keeps making my machine crash. +this static page will be here +until I can find a better solution. +clone urls and tarball urls are still functional. +. +.Bl -tag +.It src \(em dontfiles +.Dl git clone https://git.causal.agency/src +.It ascii.town +.Bl -tag +.It torus \(em collaborative ASCII art +.Dl git clone https://git.causal.agency/torus +.It play \(em some games for SSH +.Dl git clone https://git.causal.agency/play +.El +.It email +.Bl -tag +.It imbox \(em IMAP to mbox +.Dl git clone https://git.causal.agency/imbox +.It bubger \(em IMAP archive generator +.Dl git clone https://git.causal.agency/bubger +.It notemap \(em notemap +.Dl git clone https://git.causal.agency/notemap +.El +.It forks +.Bl -tag +.It shulker \(em Discord to vanilla Minecraft bridge +.Dl git clone https://git.causal.agency/shulker +.It cgit-pink \(em web frontend for git +.Dl git clone https://git.causal.agency/cgit-pink +.It dash \(em patched shell with cmake build +.Dl git clone https://git.causal.agency/dash +.El +.It games +.Bl -tag +.It wep \(em Windows Entertainment Pack recreations +.Dl git clone https://git.causal.agency/wep +.It cards \(em CARDS.DLL loader for SDL +.Dl git clone https://git.causal.agency/cards +.El +.It irc +.Bl -tag +.It scooper \(em web interface for litterbox +.Dl git clone https://git.causal.agency/scooper +.It litterbox \(em IRC logger +.Dl git clone https://git.causal.agency/litterbox +.It pounce \(em IRC bouncer +.Dl git clone https://git.causal.agency/pounce +.It catgirl \(em IRC client +.Dl git clone https://git.causal.agency/catgirl +.El +.It ports +.Bl -tag +.It jorts \(em my own ports tree for macOS +.Dl git clone https://git.causal.agency/jorts +.It exman \(em manuals for other systems +.Dl git clone https://git.causal.agency/exman +.It libretls \(em libtls for OpenSSL +.Dl git clone https://git.causal.agency/libretls +.It ports \(em Fx and Ox ports for this software +.Dl git clone https://git.causal.agency/ports +.El +.It system +.Bl -tag +.It kitd \(em process supervisor for OpenBSD +.Dl git clone https://git.causal.agency/kitd +.It catsit \(em (deprecated) process supervisor +.Dl git clone https://git.causal.agency/catsit +.El +.El diff --git a/www/photo.causal.agency/.gitignore b/www/photo.causal.agency/.gitignore new file mode 100644 index 00000000..a5f66a9d --- /dev/null +++ b/www/photo.causal.agency/.gitignore @@ -0,0 +1,2 @@ +static/ +*.JPG diff --git a/www/photo.causal.agency/2024-04-10/IMG_0832.txt b/www/photo.causal.agency/2024-04-10/IMG_0832.txt new file mode 100644 index 00000000..65724024 --- /dev/null +++ b/www/photo.causal.agency/2024-04-10/IMG_0832.txt @@ -0,0 +1,6 @@ +a red brick wall with some faded black graffiti. +in the lower third, some bricks are missing +from the outer layer in an arc shape. +along the bottom is a ledge of conrete +lightly covered in brick dust and chunks +below the missing areas above. diff --git a/www/photo.causal.agency/2024-04-10/IMG_0850.txt b/www/photo.causal.agency/2024-04-10/IMG_0850.txt new file mode 100644 index 00000000..4cbb3def --- /dev/null +++ b/www/photo.causal.agency/2024-04-10/IMG_0850.txt @@ -0,0 +1,6 @@ +grey steel beams of a building in early construction +on a background of blue sky with some light clouds. +the beams are intersecting at odd points, +implying the final building will not be a simple box. +the sun casts dark shadows into the interiors +of the I-shaped metal. diff --git a/www/photo.causal.agency/2024-04-10/IMG_0852.txt b/www/photo.causal.agency/2024-04-10/IMG_0852.txt new file mode 100644 index 00000000..707d7cd6 --- /dev/null +++ b/www/photo.causal.agency/2024-04-10/IMG_0852.txt @@ -0,0 +1,4 @@ +in the foreground, a metal construction fence. +behind that, the bright red arm of a sort of small crane. +the arm is horizontal and crushing a perpendicular piece of fence, +which has deformed smoothly under it. diff --git a/www/photo.causal.agency/2024-04-10/IMG_0858.txt b/www/photo.causal.agency/2024-04-10/IMG_0858.txt new file mode 100644 index 00000000..42f243e4 --- /dev/null +++ b/www/photo.causal.agency/2024-04-10/IMG_0858.txt @@ -0,0 +1,6 @@ +an uneven grid of old wooden-framed windows in an alley. +the red paint on the frames is peeling badly, +completely stripped in some spots. +in the reflections of the lower windows +we see the roofs of the opposite buildings +and hints of clouds in the sky. diff --git a/www/photo.causal.agency/2024-04-10/IMG_0859.txt b/www/photo.causal.agency/2024-04-10/IMG_0859.txt new file mode 100644 index 00000000..ca33d7e0 --- /dev/null +++ b/www/photo.causal.agency/2024-04-10/IMG_0859.txt @@ -0,0 +1,6 @@ +an old backetball hoop mounted in an alley. +the backboard has been graffitied +and vines have invaded. +a few red strands of net are left hanging from the hoop. +the fence behind is painted with a design of yellow, purple, white and blue. +it's the kind of hoop airbud might be hanging around. diff --git a/www/photo.causal.agency/2024-04-10/IMG_0865.txt b/www/photo.causal.agency/2024-04-10/IMG_0865.txt new file mode 100644 index 00000000..7a955fc2 --- /dev/null +++ b/www/photo.causal.agency/2024-04-10/IMG_0865.txt @@ -0,0 +1,2 @@ +deep tire tread pressed into mud in the center of an alley. +a small branch of evergreen lies to one side. diff --git a/www/photo.causal.agency/2024-04-10/IMG_0890.txt b/www/photo.causal.agency/2024-04-10/IMG_0890.txt new file mode 100644 index 00000000..9d2cdc43 --- /dev/null +++ b/www/photo.causal.agency/2024-04-10/IMG_0890.txt @@ -0,0 +1,9 @@ +a pipe coming out of a light brown brick wall. +the pipe comes out of a metal square in the centre of the wall, +travels up and left for a bit, +before continuing straight up out of frame. +opposite, in the bottom right, +is the top of a red metal grate in front +of a ground-level window. +the brick below where the pipe enters the wall +is stained dark. diff --git a/www/photo.causal.agency/2024-04-14/IMG_1054.txt b/www/photo.causal.agency/2024-04-14/IMG_1054.txt new file mode 100644 index 00000000..f4803ee2 --- /dev/null +++ b/www/photo.causal.agency/2024-04-14/IMG_1054.txt @@ -0,0 +1,5 @@ +a short wall of natural rock, +all broken up somewhat neatly +along horizontal and vertical lines. +most of the rock is cool grey, +while some parts are warm brown. diff --git a/www/photo.causal.agency/2024-04-14/IMG_1058.txt b/www/photo.causal.agency/2024-04-14/IMG_1058.txt new file mode 100644 index 00000000..21aeb189 --- /dev/null +++ b/www/photo.causal.agency/2024-04-14/IMG_1058.txt @@ -0,0 +1,6 @@ +moss on a bit of exposed natural rock +surrounded by mostly brown grass. +there is shorter, darker green and brown moss, +as well as longer lighter green moss. +some small pieces of the rock are broken off +and lay in little piles. diff --git a/www/photo.causal.agency/2024-04-14/IMG_1066.txt b/www/photo.causal.agency/2024-04-14/IMG_1066.txt new file mode 100644 index 00000000..81747287 --- /dev/null +++ b/www/photo.causal.agency/2024-04-14/IMG_1066.txt @@ -0,0 +1,10 @@ +two green buds on the end of a thin branch +on a blurry brown backdrop. +the branch enters the frame +from the bottom left corner, +and there are three other pairs of buds +along it, +out of focus. +there is a hint of another bebudded branch +in the background, +but there is otherwise very little green. diff --git a/www/photo.causal.agency/2024-04-19/IMG_1158.txt b/www/photo.causal.agency/2024-04-19/IMG_1158.txt new file mode 100644 index 00000000..e18bd6c7 --- /dev/null +++ b/www/photo.causal.agency/2024-04-19/IMG_1158.txt @@ -0,0 +1,6 @@ +a glowing amber street lamp +affixed to a telephone pole. +across its round top +there is peeling grey-brown paint. +the lamp is surrounded +by out of focus bare tree branches. diff --git a/www/photo.causal.agency/generate.sh b/www/photo.causal.agency/generate.sh new file mode 100644 index 00000000..4b30db92 --- /dev/null +++ b/www/photo.causal.agency/generate.sh @@ -0,0 +1,211 @@ +#!/bin/sh +set -eu + +mkdir -p static/preview static/thumbnail + +resize() { + local photo=$1 size=$2 output=$3 + if ! test -f $output; then + # FIXME: convert complains about not understanding XML + echo $output >&2 + convert $photo -auto-orient -thumbnail $size $output 2>/dev/null ||: + fi +} + +preview() { + local photo=$1 + local preview=preview/${photo##*/} + resize $photo 25% static/$preview + echo $preview +} + +thumbnail() { + local photo=$1 + local thumbnail=thumbnail/${photo##*/} + resize $photo 5% static/$thumbnail + echo $thumbnail +} + +encode() { + sed ' + s/&/\&/g + s/</\</g + s/"/\"/g + ' "$@" +} + +page_title() { + date -j -f '%F' $1 '+%B %e, %Y' +} + +page_head() { + local date=$1 + local title=$(page_title $date) + cat <<-EOF + <!DOCTYPE html> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <link rel="alternate" type="application/atom+xml" href="../feed.atom"> + <title>${title}</title> + <style> + html { color: #bbb; background-color: black; font-family: sans-serif; } + figure { margin: 1em; padding-top: 0.5em; text-align: center; } + img { max-width: calc(100vw - 2.5em); max-height: calc(100vh - 2.5em); } + details { max-width: 78ch; margin: 0.5em auto; } + </style> + <h1>${title}</h1> + EOF +} + +photo_info() { + local photo=$1 + ExposureTime= + FNumber= + FocalLength= + PhotographicSensitivity= + eval $( + identify -format '%[EXIF:*]' $photo 2>/dev/null | + grep -E 'ExposureTime|FNumber|FocalLength|PhotographicSensitivity' | + sed 's/^exif://' + ) +} + +photo_id() { + local photo=$1 + photo=${photo##*/} + photo=${photo%%.*} + echo $photo +} + +page_photo() { + local photo=$1 preview=$2 description=$3 + if ! test -f $description; then + description=/dev/null + fi + photo_info $photo + cat <<-EOF + <figure id="$(photo_id $photo)"> + <a href="${photo##*/}"> + <img src="../${preview}" alt="$(encode $description)"> + </a> + <figcaption> + ${ExposureTime} · + ƒ/$(bc -S 1 -e ${FNumber}) · + $(bc -e ${FocalLength}) mm · + ${PhotographicSensitivity} ISO + <details> + <summary>description</summary> + $(encode $description) + </details> + </figcaption> + </figure> + EOF +} + +index_head() { + cat <<-EOF + <!DOCTYPE html> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <link rel="alternate" type="application/atom+xml" href="feed.atom"> + <title>Photos</title> + <style> + html { color: #bbb; background-color: black; font-family: sans-serif; } + a { text-decoration: none; color: inherit; } + </style> + EOF +} + +index_page() { + local date=$1 root=${2:-} + cat <<-EOF + <h1><a href="${root}${root:+/}${date}/">$(page_title $date)</a></h1> + EOF +} + +index_photo() { + local date=$1 photo=$2 thumbnail=$3 root=${4:-} + cat <<-EOF + <a href="${root}${root:+/}${date}/#$(photo_id $photo)"> + <img src="${root}${root:+/}${thumbnail}"> + </a> + EOF +} + +Root=https://photo.causal.agency + +atom_head() { + local updated=$(date -u '+%FT%TZ') + cat <<-EOF + <?xml version="1.0" encoding="utf-8"?> + <feed xmlns="http://www.w3.org/2005/Atom"> + <title>Photos</title> + <author><name>june</name><email>june@causal.agency</email></author> + <link href="${Root}"/> + <link rel="self" href="${Root}/feed.atom"/> + <id>${Root}/</id> + <updated>${updated}</updated> + EOF +} + +atom_entry_head() { + local date=$1 + local updated=$( + date -ju -f '%s' $(stat -f '%m' static/${date}/index.html) '+%FT%TZ' + ) + cat <<-EOF + <entry> + <title>$(page_title $date)</title> + <link href="${Root}/${date}/"/> + <id>${Root}/${date}/</id> + <updated>${updated}</updated> + <content type="html"> + EOF +} + +atom_entry_tail() { + cat <<-EOF + </content> + </entry> + EOF +} + +atom_tail() { + cat <<-EOF + </feed> + EOF +} + +set -- +for date in 20*; do + mkdir -p static/${date} + page=static/${date}/index.html + if ! test -f $page; then + echo $page >&2 + page_head $date >$page + for photo in ${date}/*.JPG; do + preview=$(preview $photo) + if ! test -f static/${photo}; then + ln $photo static/${photo} + fi + page_photo $photo $preview ${photo%.JPG}.txt >>$page + done + fi + set -- $date "$@" +done + +echo static/index.html >&2 +index_head >static/index.html +echo static/feed.atom >&2 +atom_head >static/feed.atom +for date; do + index_page $date >>static/index.html + atom_entry_head $date >>static/feed.atom + for photo in ${date}/*.JPG; do + thumbnail=$(thumbnail $photo) + index_photo $date $photo $thumbnail >>static/index.html + index_photo $date $photo $thumbnail $Root | encode >>static/feed.atom + done + atom_entry_tail >>static/feed.atom +done +atom_tail >>static/feed.atom diff --git a/www/photo.causal.agency/rsync.sh b/www/photo.causal.agency/rsync.sh new file mode 100644 index 00000000..957911d2 --- /dev/null +++ b/www/photo.causal.agency/rsync.sh @@ -0,0 +1,5 @@ +#!/bin/sh +set -eu + +sh generate.sh +rsync -av static/ scout:/var/www/photo.causal.agency diff --git a/www/temp.causal.agency/up.c b/www/temp.causal.agency/up.c index 4b83b564..561a8901 100644 --- a/www/temp.causal.agency/up.c +++ b/www/temp.causal.agency/up.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 C. McEnroe <june@causal.agency> +/* Copyright (C) 2020 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/www/text.causal.agency/037-care.7 b/www/text.causal.agency/037-care.7 index 3fffd778..052a4727 100644 --- a/www/text.causal.agency/037-care.7 +++ b/www/text.causal.agency/037-care.7 @@ -27,6 +27,10 @@ Prices obviously change, by which I mean they inevitably go up, but I'm gonna give the amounts I paid in 2021\(en2022. +Also if you want more details +about any of this +please email me. +I will be happy to tell you all about it. . .Ss Medication I get HRT through @@ -65,21 +69,27 @@ for my current prescription on the public plan. . .Ss Hair removal -I've gotten laser hair removal treatments -at Dermamode with Audrey. -They're very nice there. -The initial consultation was over the phone. -I paid $1350 for 6 treatments, -in two installments -at the first and second appointments, -plus the ~$200 tax on that -before the first appointment, -I think. -It hasn't gone well for me so far, -but I'm hoping it will -now that my testosterone levels -have dropped. -I will report back. +I tried laser hair removal, +for longer than I should have. +It was a waste of time and money. +Do not believe any arguments about +its convenience over electrolysis. +. +.Pp +I've started getting electrolysis done +with Dimi. +Again, +feel free to email me for contact info. +He is very good and can do long sessions. +I really don't find it very painful, +which I think is partly my own pain tolerance +and partly good equipment and skill. +I've also found that taking acetaminophen beforehand +and dressing warmly to keep my body relaxed help. +I've paid $85 for hour-long sessions +and $160 for two-hour sessions. +I'm still early in treatment, +but I'm really happy with the results so far! . .Ss Sex & name change The form for this is @@ -101,7 +111,8 @@ so I made a donation to P10. . .Pp I paid $144 to file mine -but it's now $148. +but it's now FREE +the first time you do it. Also $17 to mail it. Surprisingly, I got an acknowledgment letter @@ -121,10 +132,12 @@ a week later. It takes another 30 days to get the certificate of change, after which you can -order a new birth certificate. -In all it took about 3 months +order a new birth certificate +and RAMQ will (slowly) send you a form +to get a new card. +In all it took about 4 months from when I mailed the application -to receiving the certificate of change. +to having ID with my name on it. . .Ss Therapy I'm not seeking therapy @@ -134,6 +147,17 @@ that's aware of it. I'll update this if I find one. . +.Ss Piercings +Ok I know this isn't trans-specific +but at least for me getting piercings +was gender-affirming. +Cuz I got nipple piercings lol. +Anyway, +I went to Mauve. +They're super nice, +really know what they're doing, +and their website has lots of info. +. .Sh AUTHORS .An june Aq Mt june@causal.agency . diff --git a/www/text.causal.agency/039-apologies.7 b/www/text.causal.agency/039-apologies.7 new file mode 100644 index 00000000..1b15076a --- /dev/null +++ b/www/text.causal.agency/039-apologies.7 @@ -0,0 +1,81 @@ +.Dd September 19, 2022 +.Dt APOLOGIES 7 +.Os "Causal Agency" +. +.Sh NAME +.Nm Apologies +.Nd making them +. +.Sh DESCRIPTION +Apologies are very important to me. +Unfortunately +I've only recently realized +how valuable they are. +I've tried to think about +what makes a good apology, +since it's not something +I was ever taught. +This is the advice +I came up with for myself, +on how to apologize. +. +.Bl -enum +.It +Make the apology. +This is the most important part. +If you feel guilty +for something you've done, +or think you might have hurt someone, +apologize. +Even if they don't need an apology, +saying sorry won't hurt. +And start with that. +Literally say +.Dq I'm sorry . +Sometimes people forget that. +.Pp +On the other side, +if you've been hurt by someone, +and you trust them, +let them know. +Give them a chance to apologize. +People don't always realize +they've made a mistake. +. +.It +Explain what you did wrong. +I think it's important +for the other person +to know you understand +how you've messed up. +Really think about this! +It's what will help you learn. +If you know you've hurt someone +but you're not sure why, +you can try asking them. +Take their answer seriously. +. +.It +Don't make excuses. +Do not talk about yourself. +Don't even mention +how you were feeling stressed that day, +or whatever. +It's not relevant. +We all make mistakes, +we all have bad days. +. +.It +Commit to doing better. +Try to learn from your mistakes. +Say it won't happen again. +Literally say +.Dq I won't do that again . +And then try your hardest to make that true. +An apology is a commitment, +not something you're done with +once you've said it. +.El +. +.Sh AUTHORS +.An june Aq Mt june@causal.agency diff --git a/www/text.causal.agency/040-sound-memory.7 b/www/text.causal.agency/040-sound-memory.7 new file mode 100644 index 00000000..c995de08 --- /dev/null +++ b/www/text.causal.agency/040-sound-memory.7 @@ -0,0 +1,165 @@ +.Dd November 14, 2022 +.Dt SOUND-MEMORY 7 +.Os "Causal Agency" +. +.Sh NAME +.Nm Sound Memory +.Nd associations +. +.Sh DESCRIPTION +.Ss Talking Heads \(em "Remain In Light" +The first time I gave this album a serious listen +was when I was going for several-hour walks +at 4 in the morning in, +I think, +fall 2020. +I would stay up all night, +go out walking at 4am +for a couple hours, +come home, +eat +.Dq breakfast +and go to sleep. +I listened to this album +walking on completely empty +big city streets +in the dark. +. +.Ss Buffy Sainte-Marie \(em Up Where We Belong +I started listening to this album +after hearing it many mornings +walking into the cafe on my block +back in 2019. +I could tell Vincent was working +if I heard this when I opened the door. +. +.Ss Molasses \(em Trilogie: Toil & Peaceful Life +I listened to this when I had 8am classes +in CEGEP. +In particular my first semester philosophy course, +which was in the forum. +I usually got there even earlier +because of how the bus schedules worked out. +There was another girl in my class, +who I always sat next to, +who also got there early, +but we never spoke outside of class. +. +.Ss Arcade Fire \(em Funeral +This album just feels like walking outside +in fresh snow in early winter, +you know? +. +.Ss Molasses \(em Trouble at Jinx Hotel +I listened to this when I was looking for an apartment. +I specifically remember listening to it +walking down Clark toward my new place +to pick up my keys. +. +.Ss Arcade Fire \(em Neon Bible +The song +.Dq "No Cars Go" +is strongly associated for me +with my earliest gender feelings. +It's how I date when I first +started to feel like something was wrong. +The Suburbs was released in 2010, +so I was probably listening to Neon Bible +in 2011. +Ten years between that +and coming out. +. +.Ss "Do Make Say Think" \(em "You You're a History In Rust" +I remember hearing +.Dq "A Tender History In Rust" +for the first time +at the office of my first job. +Me and my coworkers stayed late, +probably on a Friday night, +drinking free tech startup booze. +. +.Ss mewithoutYou \(em It's All Crazy! It's All False! It's All a Dream! It's Alright +I exclusively listened to this album +on a high school trip to Europe. +Every morning when we got on the bus, +I heard +.Dq Every Thought a Thought of You +and every night before bed +I listened to +.Dq The King Beetle on a Coconut Estate . +. +.Ss Arcade Fire \(em The Suburbs +I listened to this album a tonne +when I was playing +Minecraft and Urban Terror +with my online friends +while I was in high school. +In particular I remember +a backyard shed World of Padman map +and the apartments Minecraft world. +. +.Ss Arcade Fire \(em Reflektor +I associate +.Dq Afterlife +with the walk between Laurier metro +and my first job, +in the winter. +Must've just been how the timing worked out +with my commute at the time. +. +.Ss Swans \(em To Be Kind +I listened to this on one of my playthroughs +of Half-Life 2. +In particular I associate +.Dq Bring the Sun / Toussaint L'Ouverture +with the Water Hazard chapter. +. +.Ss Wrekmeister Harmonies \(em Light Falls +For a while I put this on whenever I +left my apartment to go somewhere +and it was already dark, +so probably winter. +. +.Ss St. Vincent \(em MASSEDUCTION +This, +along with the next one, +I think were all I listened to +on a family vacation +to Quebec City and New Brunswick +some years ago. +. +.Ss SOPHIE \(em Oil of Every Pearl's Un-Insides +Many hours on the road +on that family vacation. +Two albums on repeat. +. +.Ss Julia Holter \(em Aviary +This is another album +I listened to when I was taking +walks at 4am. +I wasn't in a good place. +Yet. +. +.Ss Beep Test \(em Laugh Track +A tape from the first act +at one of my favourite shows +I've ever been to, +at La Sotterenea +in Suoni 2019. +I wish I had been out already. +. +.Ss The Armed \(em Only Love +The third of the albums I listened to +on those dark walks. +I listened to it loud, +this album's mixing needs it. +. +.Ss Eliza Kavtion \(em The Rez That Summer +A favourite local artist. +I remember vividly the first time +I heard her play, +opening for Wrekmeister Harmonies +at La Vitrola in 2018. +. +.Sh AUTHORS +.An june Aq Mt june@causal.agency diff --git a/www/text.causal.agency/041-albums-2022.7 b/www/text.causal.agency/041-albums-2022.7 new file mode 100644 index 00000000..48bd3c3d --- /dev/null +++ b/www/text.causal.agency/041-albums-2022.7 @@ -0,0 +1,185 @@ +.Dd December 21, 2022 +.Dt ALBUMS-2022 7 +.Os "Causal Agency" +. +.Sh NAME +.Nm albums 2022 +.Nd review +. +.Sh DESCRIPTION +it's the year-end review +of albums I listened to. +same as last year, +I added any albums I got into +this year to a playlist. +I've actually done that +every year since 2018. +maybe I'll review +those old playlists some time. +. +.Ss ZHAOZE \(em SUMMER INSECTS TALK ABOUT ICE (2021) +it's a five-and-a-half-minute album! +you can loop it however long you want. +it's really lovely. +.Pp +favourite track: +ON HORSEBACK, TO FARAWAY +. +.Ss KATE BUSH \(em HOUNDS OF LOVE (1985) +first of all I do not watch that one show. +I've known that track for a while actually. +I mean I probably first heard the CHROMATICS cover. +but anyway, +I think someone mentioned this album +on IRC at just the right time +and I put it on. +the second half really shines tbh. +love a concept album. +.Pp +favourite tracks: +RUNNING UP THAT HILL, +HOUNDS OF LOVE, +AND DREAM OF SHEEP, +WATCHING YOU WITHOUT ME, +THE MORNING FOG. +. +.Ss GODSPEED YOU! BLACK EMPEROR \(em ALL LIGHTS FUCKED ON THE HAIRY AMP DROOLING (1994) +didn't expect to hear this probably ever. +still wild that it finally got uploaded. +and to be honest I'm a little mad +that it's actually good. +like yeah it's not a godspeed album +but it holds up as a tape on its own. +it's the kind of shit I listen to. +also can't believe some people +still thought it was fake. +like have you not heard +any other efrim menuck projects? +.Pp +favourite tracks: +$13.13, +DIMINISHING SHINE, +DADMOMDADDY, +333 FRAMES PER SECOND, +ALL ANGELS GONE. +. +.Ss BLACK DRESSES \(em FORGET YOUR OWN FACE (2022) +woops I think I only listened to this like twice. +will need to revisit it later for sure. +I'll like it. +. +.Ss BACKXWASH \(em I LIE HERE BURIED WITH MY RINGS AND MY DRESSES (2021) +only got into this album +after hearing it live this summer. +was the first show I went to in years +and it was really fucking good. +gotta listen to this shit loud. +sampling godspeed for a beat fucks. +honestly back to back bangers. +.Pp +favourite tracks: +I LIE HERE BURIED WITH MY RINGS AND MY DRESSES, +TERROR PACKETS, +SONG OF SINNERS, +BURN TO ASHES. +. +.Ss PHILIP GLASS ENSEMBLE \(em EINSTEIN ON THE BEACH (1979) +actually just the knee plays +because I can't be bothered +listening to all of it. +and I'm embarrassed by how much +I enjoy this avant-garde bullshit. +like ok just sing repeating numbers at me +and my brain is happy. +what is this? +my kink? +anyway I also have kind of an obsession +with the +.Dq story of love +in knee 5. +I fucking hate it. +but it's delivered so well. +and that violin though! +.Pp +favourite tracks: +KNEE 1, +KNEE 5. +. +.Ss KANYE WEST \(em YEEZUS (2013) +ok look I listened to this +before recent events. +what the fuck. +it's a really good album though? +pretty sure I listened to it +because bound 2 kept getting in my head, +because of that minecraft parody parody +wayne did ages ago. +.Pp +favourite tracks: +BLACK SKINHEAD, +HOLD MY LIQUOR, +BLOOD ON THE LEAVES, +BOUND 2. +. +.Ss FLYING RACCOON SUIT \(em AFTERGLOW (2021) +I've listened to the whole album +a few times +but I'm mostly just here +for the title track. +this also happened to be +dropped in IRC at just the right time. +good ska-punk-type shit. +and I like lisps ok. +.Pp +favourite track: +AFTERGLOW. +. +.Ss RAMSHACKLE GLORY \(em LIVE THE DREAM (2011) +one of those albums +I don't know why I took so long +to get to. +I've been listening to johnny hobo +since I was like in high school. +ramshackle is a little more hopeful +and I love that. +your heart is a muscle the size of your fist. +keep on loving. +keep on fighting. +.Pp +favourite tracks: +WE ARE ALL COMPOST IN TRAINING, +NEVER COMING HOME, +YOUR HEART IS A MUSCLE THE SIZE OF YOUR FIST. +. +.Ss LES RALLIZES D\('ENUD\('ES \(em THE OZ TAPES (2022) +a pleasant surprise in someone's playlist. +lately I've been listening to this +in the metro to or from electrolysis. +it's good listening for that. +bold to have two versions +of the same 24-minute song +on the same release. +.Pp +favourite tracks: +A SHADOW ON OUR JOY, +THE LAST ONE_1970 (ver.2). +. +.Ss LINGUA IGNOTA \(em SINNER GET READY (2021) +another I'm only getting into +after hearing it live. +just last sunday actually. +was a good show. +people will go wild +to hear a cover live for real. +.Pp +favourite tracks: +I WHO BEND THE TALL GRASSES, +PENNSYLVANIA FURNACE, +PERPETUAL FLAME OF CENTRALIA. +. +.Sh AUTHORS +.An june Aq Mt june@causal.agency +.Pp +I started writing this +before I saw LINGUA IGNOTA. +good thing I waited. diff --git a/www/text.causal.agency/042-comfort-music.7 b/www/text.causal.agency/042-comfort-music.7 new file mode 100644 index 00000000..445e04c3 --- /dev/null +++ b/www/text.causal.agency/042-comfort-music.7 @@ -0,0 +1,62 @@ +.Dd February 23, 2024 +.Dt COMFORT-MUSIC 7 +.Os "Causal Agency" +. +.Sh NAME +.Nm comfort music +.Nd feel better +. +.Sh DESCRIPTION +it's been a while. +and I'm on almost no sleep +and haven't eaten a real meal +since noon. +which is a state I've written +at least a couple posts in before, +so what better time +to return to what has apparently +become this blog's format: +lists of some music I like. +. +.Pp +this is a list of music that comforts me. +. +.Bl -bullet +.It +knee play 5, from einstein on the beach. +I like the organ and the counting and the cadence of the story. +.It +low \(em words. +and I'm tired. +.It +godspeed you! black emperor \(em storm. +this is like my original comfort music. +been listening to it since I was teenage. +the grooves are worn deep in my mind. +.It +set fire to flames \(em love song for 15 ontario (w/ singing police car). +I like how it ends. +.It +va, from the beginner's guide. +I think that's the whole point. +though maybe it's too sad +to be truly comforting. +.It +undertale, from undertale. +what can I say? +.It +wrekmeister harmonies \(em covered in blood from invisible wounds. +I find quite a bit of the album comforting really. +I'm picking this one because I like the cadence +of the lyrics. +.It +lingua ignota \(em pennsylvania furnace and perpetual flame of centralia. +these are really my go to in recent times. +I like waiting for the next line. +.El +. +.Sh AUTHORS +.An june Aq Mt june@causal.agency +.Pp +I don't think I've said anything +very interesting here. diff --git a/www/text.causal.agency/043-little-blessings.7 b/www/text.causal.agency/043-little-blessings.7 new file mode 100644 index 00000000..957c6289 --- /dev/null +++ b/www/text.causal.agency/043-little-blessings.7 @@ -0,0 +1,78 @@ +.Dd March 24, 2024 +.Dt LITTLE-BLESSINGS 7 +.Os "Causal Agency" +. +.Sh NAME +.Nm little blessings +.Nd life's +. +.Sh DESCRIPTION +today I went out to go around. +run some errands and do some shopping. +along the way I was given +several of life's little blessings. +. +.Pp +while walking on ste-cath +between berri and complexe desjardins, +there was a somewhat disheveled man +walking in the same direction and singing. +he had a beautiful voice. +he was singing a sad song in french, +and he sung it well and enunciated every word. +. +.Pp +in the mcdonald's at complexe desjardins, +while waiting for my order, +there were what appeared to be +a teenager and her younger brother, +who must have been +looking at the display of +current happy meal toys. +the teenager was playing smash or pass, +to the amusement of the younger one. +they got ice cream +and ate it across the room from me downstairs. +. +.Pp +later, +taking the 24 home from atwater +carrying my new vacuum cleaner, +the bus got lost. +I think the driver missed the stop +and tried to compensate +by turning north onto peel +and stopping there. +but then he had to keep going up peel. +he turned right onto docteur-penfield, +which just brings you further up the mountain. +when it met des pins, +he turned left and pulled over, +asking for guidance over the radio. +we got moving again, +back towards peel. +that's how I ended up +on a 24 +.Dq sherbrooke +east, +facing west on des pins. +it was actually quite scenic. +and amusing. +I was in no rush. +. +.Pp +after getting back onto sherbrooke, +the bus had to take another detour, +this one planned. +so my ride on the 24, +which normally only drives on sherbrooke, +ended up going on peel, +docteur-penfield, +des pins, +de bleury, +ren\('e-l\('evesque +and saint-laurent. +it was a very exciting bus trip. +. +.Sh AUTHORS +.An june Aq Mt june@causal.agency diff --git a/www/text.causal.agency/Makefile b/www/text.causal.agency/Makefile index c5555274..a8683a20 100644 --- a/www/text.causal.agency/Makefile +++ b/www/text.causal.agency/Makefile @@ -38,15 +38,24 @@ TXTS += 035-addendum-2021.txt TXTS += 036-compassion.txt TXTS += 037-care.txt TXTS += 038-agency.txt +TXTS += 039-apologies.txt +TXTS += 040-sound-memory.txt +TXTS += 041-albums-2022.txt +TXTS += 042-comfort-music.txt +TXTS += 043-little-blessings.txt all: colb ${TXTS} -.SUFFIXES: .7 .txt +.SUFFIXES: .7 .fmt .txt .7.txt: mandoc -T utf8 $< | ./colb > $@ touch -m -r $< $@ +.fmt.txt: + fmt $< | sed '1,/^$$/d' > $@ + touch -m -r $< $@ + feed.atom: feed.sh colb ${TXTS} sh feed.sh > feed.atom diff --git a/www/text.causal.agency/feed.sh b/www/text.causal.agency/feed.sh index 668046ef..71bbf662 100644 --- a/www/text.causal.agency/feed.sh +++ b/www/text.causal.agency/feed.sh @@ -27,6 +27,7 @@ set -- *.txt shift $(( $# - 20 )) for txt; do entry="${txt%.txt}.7" + test -f "$entry" || entry="${txt%.txt}.fmt" date=$(grep '^[.]Dd' "$entry" | cut -c 5-) title=$(grep -m 1 '^[.]Nm' "$entry" | cut -c 5- | encode) summary=$(grep '^[.]Nd' "$entry" | cut -c 5- | encode) |