diff options
-rw-r--r-- | bin/.gitignore | 1 | ||||
-rw-r--r-- | bin/Makefile | 1 | ||||
-rw-r--r-- | bin/README.7 | 6 | ||||
-rw-r--r-- | bin/man1/typer.1 | 69 | ||||
-rw-r--r-- | bin/typer.c | 170 |
5 files changed, 4 insertions, 243 deletions
diff --git a/bin/.gitignore b/bin/.gitignore index b49c2b39..02f0536f 100644 --- a/bin/.gitignore +++ b/bin/.gitignore @@ -34,7 +34,6 @@ shotty sup tags title -typer up when xx diff --git a/bin/Makefile b/bin/Makefile index c998d417..8564f59b 100644 --- a/bin/Makefile +++ b/bin/Makefile @@ -44,7 +44,6 @@ LINUX += psfed TLS += downgrade TLS += relay -TLS += typer MANS = ${BINS:%=man1/%.1} MANS.BSD = ${BSD:%=man1/%.1} diff --git a/bin/README.7 b/bin/README.7 index cdae4def..f3407978 100644 --- a/bin/README.7 +++ b/bin/README.7 @@ -1,4 +1,4 @@ -.Dd September 8, 2021 +.Dd September 15, 2021 .Dt BIN 7 .Os "Causal Agency" . @@ -15,7 +15,7 @@ and Some tools target Linux. . .Pp -.Bl -tag -width "fbclock(1)" -compact +.Bl -tag -width "git-comment(1)" -compact .It Xr beef 1 Befunge-93 interpreter .It Xr bibsort 1 @@ -28,6 +28,8 @@ backlight brightness control run C statements .It Xr dehtml 1 extract text from HTML +.It Xr downgrade 1 +IRC features for all .It Xr dtch 1 detached sessions .It Xr ever 1 diff --git a/bin/man1/typer.1 b/bin/man1/typer.1 deleted file mode 100644 index 0322d108..00000000 --- a/bin/man1/typer.1 +++ /dev/null @@ -1,69 +0,0 @@ -.Dd July 9, 2021 -.Dt TYPER 1 -.Os -. -.Sh NAME -.Nm typer -.Nd type all day -. -.Sh SYNOPSIS -.Nm -.Op Fl PRv -.Op Fl c Ar cert -.Op Fl j Ar chan -.Op Fl n Ar nick -.Op Fl p Ar port -.Op Fl u Ar user -.Ar host -. -.Sh DESCRIPTION -.Nm -is an IRC bot -that types whenever anyone else does. -The arguments are as follows: -.Bl -tag -width Ds -.It Fl P -Request the -.Sy causal.agency/passive -vendor-specific capability. -.It Fl R -Reverse -.Nm . -Send other users' typing indicators -as regular messages for all to see. -.It Fl c Ar cert -Use the TLS client certificate -and private key loaded from -.Ar cert . -.It Fl j Ar chan -Join a channel. -.It Fl n Ar nick -Set the nickname. -The default is -.Nm . -.It Fl p Ar port -Connect to -.Ar port . -The default is 6697. -.It Fl u Ar user -Set the username. -The default is -.Nm . -.It Fl v -Log IRC protocol to standard error. -.It Ar host -Connect to -.Ar host . -.El -. -.Sh STANDARDS -.Bl -item -.It -.Rs -.%A MuffinMedic -.%A James Wheare -.%T IRCv3 typing client tag -.%I IRCv3 Working Group -.%U https://ircv3.net/specs/client-tags/typing -.Re -.El diff --git a/bin/typer.c b/bin/typer.c deleted file mode 100644 index b21761d4..00000000 --- a/bin/typer.c +++ /dev/null @@ -1,170 +0,0 @@ -/* Copyright (C) 2021 C. 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/>. - * - * Additional permission under GNU GPL version 3 section 7: - * - * If you modify this Program, or any covered work, by linking or - * combining it with LibreSSL (or a modified version of that library), - * containing parts covered by the terms of the OpenSSL License and the - * original SSLeay license, the licensors of this Program grant you - * additional permission to convey the resulting work. Corresponding - * Source for a non-source form of such a combination shall include the - * source code for the parts of LibreSSL used as well as that of the - * covered work. - */ - -#include <err.h> -#include <stdarg.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sysexits.h> -#include <tls.h> -#include <unistd.h> - -static bool verbose; -static struct tls *client; -static const char *join; -static bool reverse; - -static void clientWrite(const char *ptr, size_t len) { - if (verbose) printf("%.*s", (int)len, ptr); - while (len) { - ssize_t ret = tls_write(client, ptr, len); - if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT) continue; - if (ret < 0) errx(EX_IOERR, "tls_write: %s", tls_error(client)); - ptr += ret; - len -= ret; - } -} - -static void format(const char *format, ...) { - char buf[1024]; - va_list ap; - va_start(ap, format); - int len = vsnprintf(buf, sizeof(buf), format, ap); - va_end(ap); - if ((size_t)len > sizeof(buf) - 1) errx(EX_DATAERR, "message too large"); - clientWrite(buf, len); -} - -static void handle(char *line) { - char *tags = NULL; - char *origin = NULL; - if (line && line[0] == '@') tags = 1 + strsep(&line, " "); - if (line && line[0] == ':') origin = 1 + strsep(&line, " "); - char *cmd = strsep(&line, " "); - if (!cmd) return; - if (!strcmp(cmd, "CAP")) { - char *param = strsep(&line, " "); - if (!param) errx(EX_PROTOCOL, "CAP missing parameter"); - if (!strcmp(param, "NAK")) { - errx(EX_CONFIG, "server does not support %s", line); - } - format("CAP END\r\n"); - } else if (!strcmp(cmd, "001") && join) { - format("JOIN %s\r\n", join); - } else if (!strcmp(cmd, "PING")) { - format("PONG %s\r\n", line); - } - if (strcmp(cmd, "TAGMSG") || !tags || !origin) return; - if (!strstr(tags, "typing=")) return; - char *nick = strsep(&origin, "!"); - if (*line == ':') line++; - if (!reverse) { - format("@%s TAGMSG %s\r\n", tags, line); - } else if (strstr(tags, "typing=active")) { - format("PRIVMSG %s :\u2328\uFE0F %s is typing!\r\n", line, nick); - } else if (strstr(tags, "typing=paused")) { - format("PRIVMSG %s :\U0001F914 %s is thinking!\r\n", line, nick); - } else if (strstr(tags, "typing=done")) { - format("PRIVMSG %s :\u270B %s stopped typing!\r\n", line, nick); - } -} - -int main(int argc, char *argv[]) { - const char *host = NULL; - const char *port = "6697"; - const char *cert = NULL; - const char *nick = "typer"; - const char *user = "typer"; - bool passive = false; - - for (int opt; 0 < (opt = getopt(argc, argv, "PRc:j:n:p:u:v"));) { - switch (opt) { - break; case 'P': passive = true; - break; case 'R': reverse = true; - break; case 'c': cert = optarg; - break; case 'j': join = optarg; - break; case 'n': nick = optarg; - break; case 'p': port = optarg; - break; case 'u': user = optarg; - break; case 'v': verbose = true; - break; default: return EX_USAGE; - } - } - if (optind == argc) errx(EX_USAGE, "host required"); - host = argv[optind]; - - client = tls_client(); - if (!client) errx(EX_SOFTWARE, "tls_client"); - - struct tls_config *config = tls_config_new(); - if (!config) errx(EX_SOFTWARE, "tls_config_new"); - - if (cert) { - int error = tls_config_set_keypair_file(config, cert, cert); - if (error) errx(EX_CONFIG, "%s: %s", cert, tls_config_error(config)); - } - - int error = tls_configure(client, config); - if (error) errx(EX_SOFTWARE, "tls_configure: %s", tls_error(client)); - tls_config_free(config); - - error = tls_connect(client, host, port); - if (error) errx(EX_UNAVAILABLE, "tls_connect: %s", tls_error(client)); - - format( - "CAP REQ :message-tags%s\r\n" - "NICK %s\r\n" - "USER %s 0 * :typer\r\n", - (passive ? " causal.agency/passive" : ""), - nick, user - ); - - size_t len = 0; - char buf[4096]; - for (;;) { - ssize_t read = tls_read(client, &buf[len], sizeof(buf) - len); - if (read == TLS_WANT_POLLIN || read == TLS_WANT_POLLOUT) continue; - if (read < 0) errx(EX_IOERR, "tls_read: %s", tls_error(client)); - if (!read) errx(EX_UNAVAILABLE, "server disconnected"); - len += read; - - char *crlf; - char *line = buf; - for (;;) { - crlf = memmem(line, &buf[len] - line, "\r\n", 2); - if (!crlf) break; - crlf[0] = '\0'; - if (verbose) printf("%s\n", line); - handle(line); - line = &crlf[2]; - } - len -= line - buf; - memmove(buf, line, len); - } -} |