#if 0 /*─────────────────────────────────────────────────────────────────╗ │ To the extent possible under law, Justine Tunney has waived │ │ all copyright and related or neighboring rights to this file, │ │ as it is written in the following disclaimers: │ │ • http://unlicense.org/ │ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif #include "libc/calls/calls.h" #include "libc/calls/struct/timespec.h" #include "libc/calls/termios.h" #include "libc/errno.h" #include "libc/runtime/runtime.h" #include "libc/stdio/append.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" #include "libc/sysv/consts/o.h" #include "libc/time.h" #include "third_party/getopt/getopt.internal.h" #include "third_party/musl/passwd.h" /** * @fileoverview program for broadcasting message to all terminals, e.g. * * o//examples/wall.com hello friends * * Will place some bold text into the top left corners of all terminals: * * Broadcast message from jart@host (pts/4) (Tue Oct 11 03:52:24 2022): * hello friends * * It's useful for having one terminal tab notify your other ones when * something like a long running job completes. In the old days back * when unix systems had multiple users, the wall command provided the * ultimate lulz especially if it's a setuid binary with root privs. */ #define GETOPTS "v" #define USAGE \ "\ Usage: wall.com [-v] [TEXTMSG] [pw_name, GetHost()); if (isatty(0) && (s = ttyname(0))) appendf(&msg, " (%s)", s); appendf(&msg, " (%s):\r\n", GetTime()); appends(&msg, "\e[K"); // append broadcast message if (optind < argc) { // use cli arguments as message if they exist for (int i = 0; optind + i < argc; ++i) { if (i) appends(&msg, " "); for (s = argv[optind + i]; *s; ++s) { if (*s == '\n') { appends(&msg, "\r\n\e[K"); } else { appendw(&msg, *s & 255); } } } } else { // otherwise use stdin as message ssize_t i, rc; char buf[512]; while ((rc = read(0, buf, sizeof(buf))) > 0) { for (i = 0; i < rc; ++i) { if (buf[i] == '\n') { appends(&msg, "\r\n\e[K"); // clear line forward } else { appendw(&msg, buf[i] & 255); } } } } appends(&msg, "\r\n\e[K\e[0m\e8"); // restore // try to send message to all pseudoteletypewriters for (int i = 0; i < 100; ++i) { int fd; char pts[32]; snprintf(pts, sizeof(pts), "/dev/pts/%d", i); if ((fd = open(pts, O_WRONLY | O_NOCTTY)) == -1) { if (errno == ENOENT) continue; if (g_verbose) perror(pts); } write(fd, msg, appendz(msg).i); close(fd); } return 0; }