From 6962404ce5bf6d8a219ff61c0a1e93944ed83afe Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Wed, 11 Mar 2026 22:35:46 +0000 Subject: util/spkmodem-recv: portability and code cleanup borrowing recent improvements from nvmutil Signed-off-by: Leah Rowe --- util/spkmodem_recv/spkmodem-recv.c | 141 +++++++++++++++++++++++++++++++------ 1 file changed, 120 insertions(+), 21 deletions(-) (limited to 'util') diff --git a/util/spkmodem_recv/spkmodem-recv.c b/util/spkmodem_recv/spkmodem-recv.c index 38ceb72a..531c1c46 100644 --- a/util/spkmodem_recv/spkmodem-recv.c +++ b/util/spkmodem_recv/spkmodem-recv.c @@ -7,13 +7,36 @@ * This version is heavily modified, re-written based on OpenBSD Kernel Source * File Style Guide (KNF); this change is Copyright 2023,2026 Leah Rowe. */ -#include +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 500 +#endif + +#ifdef __OpenBSD__ +#include +#endif + #include #include +#include #include #include #include +static int set_ascii_bit(void); +static void handle_audio(void), decode_pulse(void), print_char(void), + print_stats(void); +static void err(int nvm_errval, const char *msg, ...); +static const char * getnvmprogname(void); +static void set_err_if_unset(int x); + +#if defined(__OpenBSD__) && defined(OpenBSD) +#if OpenBSD >= 509 +#ifndef HAVE_PLEDGE +#define HAVE_PLEDGE 1 +#endif +#endif +#endif + #define SAMPLES_PER_FRAME 240 #define MAX_SAMPLES (2 * SAMPLES_PER_FRAME) #define FREQ_SEP_MIN 5 @@ -23,62 +46,86 @@ #define FREQ_DATA_MAX 60 #define THRESHOLD 500 -#define ERR() (errno = errno ? errno : ECANCELED) #define reset_char() ascii = 0, ascii_bit = 7 -#define err_if(x) if (x) err(ERR(), NULL) + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 1 +#endif + +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 0 +#endif signed short frame[MAX_SAMPLES], pulse[MAX_SAMPLES]; int ringpos, debug, freq_data, freq_separator, sample_count, ascii_bit = 7; char ascii = 0; -int set_ascii_bit(void); -void handle_audio(void), decode_pulse(void), print_char(void), - print_stats(void); +static const char *argv0; int main(int argc, char *argv[]) { -#ifdef __OpenBSD__ - err_if (pledge("stdio", NULL) == -1); + int c; + +#ifdef HAVE_PLEDGE +#if HAVE_PLEDGE > 0 + if (pledge("stdio", NULL) == -1) + err(errno, "pledge"); +#endif #endif - for (int c; (c = getopt(argc, argv, "d")) != -1;) - err_if (!(debug = (c == 'd'))); + while (c != -1) { + c = getopt(argc, argv, "d"); + + if (c == 'd') + debug = 1; + else if (c != -1) + err(EINVAL, "Invalid argument"); + } + setvbuf(stdout, NULL, _IONBF, 0); + while (!feof(stdin)) handle_audio(); - if (errno && debug) - err(errno, "Unhandled error, errno %d", errno); - return errno; + + return EXIT_SUCCESS; } -void +static void handle_audio(void) { + int sample; + if (sample_count > (3 * SAMPLES_PER_FRAME)) sample_count = reset_char(); + if ((freq_separator <= FREQ_SEP_MIN) || (freq_separator >= FREQ_SEP_MAX) || (freq_data <= FREQ_DATA_MIN) || (freq_data >= FREQ_DATA_MAX)) { decode_pulse(); return; } + if (set_ascii_bit() < 0) print_char(); + sample_count = 0; - for (int sample = 0; sample < SAMPLES_PER_FRAME; sample++) + + for (sample = 0; sample < SAMPLES_PER_FRAME; sample++) decode_pulse(); } -void +static void decode_pulse(void) { int next_ringpos = (ringpos + SAMPLES_PER_FRAME) % MAX_SAMPLES; + freq_data -= pulse[ringpos]; freq_data += pulse[next_ringpos]; freq_separator -= pulse[next_ringpos]; fread(frame + ringpos, 1, sizeof(frame[0]), stdin); + if (ferror(stdin) != 0) - err(ERR(), "Could not read from frame."); + err(errno, "Could not read from frame."); pulse[ringpos] = (abs(frame[ringpos]) > THRESHOLD) ? 1 : 0; freq_separator += pulse[ringpos++]; @@ -86,32 +133,84 @@ decode_pulse(void) ++sample_count; } -int +static int set_ascii_bit(void) { if (debug) print_stats(); + if (freq_data < FREQ_DATA_THRESHOLD) ascii |= (1 << ascii_bit); + --ascii_bit; return ascii_bit; } -void +static void print_stats(void) { long stdin_pos; - err_if ((stdin_pos = ftell(stdin)) == -1); + + if ((stdin_pos = ftell(stdin)) == -1) + err(errno, "ftell stdin"); + printf ("%d %d %d @%ld\n", freq_data, freq_separator, FREQ_DATA_THRESHOLD, stdin_pos - sizeof(frame)); } -void +static void print_char(void) { if (debug) printf("<%c, %x>", ascii, ascii); else printf("%c", ascii); + reset_char(); } + +static void +err(int nvm_errval, const char *msg, ...) +{ + va_list args; + + fprintf(stderr, "%s: ", getnvmprogname()); + + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); + + set_err_if_unset(nvm_errval); + fprintf(stderr, ": %s", strerror(errno)); + + fprintf(stderr, "\n"); + + exit(EXIT_FAILURE); +} + +static const char * +getnvmprogname(void) +{ + const char *p; + + if (argv0 == NULL || *argv0 == '\0') + return ""; + + p = strrchr(argv0, '/'); + + if (p) + return p + 1; + else + return argv0; +} + +static void +set_err_if_unset(int x) +{ + if (errno) + return; + if (x > 0) + errno = x; + else + errno = ECANCELED; +} -- cgit v1.2.1