From 1278fa3e472a9010d71f0af6f21b0bff28420960 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Mon, 25 Sep 2023 12:40:37 -0600 Subject: [PATCH] Add code and readme --- LICENSE => COPYING.txt | 0 README.md | 63 +++++++++++++++++++++++++++++++-- baud.c | 80 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 2 deletions(-) rename LICENSE => COPYING.txt (100%) create mode 100644 baud.c diff --git a/LICENSE b/COPYING.txt similarity index 100% rename from LICENSE rename to COPYING.txt diff --git a/README.md b/README.md index 8fba4b7..d926fec 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,62 @@ -# baud +--- +title: baud.c +--- -Modem simulator \ No newline at end of file +[baud.c](baud.c) is a program to simulate going through a modem. +It reads stdin, and prints it to stdout at the provided baud rate (bits per second). + + +Building +-------- + +Download [baud.c](baud.c). Change to that directory, and type + + make baud + +That will generate a file named `baud` in whatever directory you're in. +If you like, +you can put it in `~/bin` or `~/.local/bin` or `/usr/games/bin` or +wherever you prefer. + + +Running +------- + +If you'd like to see what life was like when I got my first modem, try + + cat file | ./baud 110 40 + +Run that for a few hours, then try + + cat file | ./baud 1200 20 + +And you will understand how mind-blowingly fast 1200 baud modems were at the time. + + frotz zork1.zip | ./baud 4800 + +Gives Zork a retro vibe, +without being so slow that it's aggravating. +I don't think more than a dozen or so people every played Zork over a modem link, +but whatever. + + +Why +--- + +Every 10 years or so, somebody asks me for this program. +I don't know why. + +The other day it happened again, and I couldn't find it soon enough, +so I just wrote it again from scratch. +I'm putting it on my web site so I don't have to write it again. + + +License +------- + +I'm placing this in the public domain. +So there's no license. + +Some jurisdictions don't recognize the existence of a public domain. +If you live in one of those, +you can use the terms of [Creative Commons 0](COPYING.txt). diff --git a/baud.c b/baud.c new file mode 100644 index 0000000..4b02987 --- /dev/null +++ b/baud.c @@ -0,0 +1,80 @@ +/* + * Pretend to be a modem by throttling output. + * + * 2023-09-12 + * Neale Pickett + * + * To the extent possible under law, + * I waive all copyright and related or neighboring rights to this software. + */ + +#include +#include +#include +#include +#include + +const int MICROSECOND = 1; +const int MILLISECOND = 1000 * MICROSECOND; +const int SECOND = 1000 * MILLISECOND; + +const int NOISINESS_DENOMINATOR = 36000; +const int NOISELEN_DEFAULT = 16; + +int +usage(char *me, char *error) { + if (error) { + fprintf(stderr, "ERROR: %s\n", error); + } + fprintf(stderr, "Usage: %s BAUD [NOISINESS] [NOISELEN]\n", me); + fprintf(stderr, "\n"); + fprintf(stderr, "Reads stdin, and writes it back to stdout at BAUD bits per second.\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "NOISINESS\tEvery bit can begin line noise, with probability NOISINESS/%d\n", NOISINESS_DENOMINATOR); + fprintf(stderr, "NOISELEN\tUp to this many bits of noise happens per burst (default: %d)\n", NOISELEN_DEFAULT); + return EX_USAGE; +} + +int +main(int argc, char *argv[]) { + if (argc < 2) { + return usage(argv[0], NULL); + } + + int baud = atoi(argv[1]); + if (baud < 1) { + return usage(argv[0], "Invalid baud rate"); + } + + int noisiness = 0; + if (argc > 2) { + noisiness = atoi(argv[2]); + } + int noiselen = NOISELEN_DEFAULT; + if (argc > 3) { + noiselen = atoi(argv[3]); + } + + int cps = baud / 10; // 8N1 has 10 bits per octet: 8 data, 1 start, 1 parity + int delay = SECOND / cps; + int noisybits = 0; + int c; + while ((c = getchar()) != EOF) { + usleep(delay); + for (int bit = 0; bit < 8; bit++) { + int r = rand() % NOISINESS_DENOMINATOR; + if (r < noisiness) { + noisybits = rand() % noiselen; + } + + if (noisybits) { + c ^= (rand() & 1) << bit; + noisybits -= 1; + } + } + putchar(c); + fflush(stdout); + } + + return EX_OK; +}