1*b76a7d7eSrillig /* $NetBSD: morse.c,v 1.23 2024/10/12 19:26:24 rillig Exp $ */ 242fb1b9dScgd 361f28255Scgd /* 442fb1b9dScgd * Copyright (c) 1988, 1993 542fb1b9dScgd * The Regents of the University of California. All rights reserved. 661f28255Scgd * 761f28255Scgd * Redistribution and use in source and binary forms, with or without 861f28255Scgd * modification, are permitted provided that the following conditions 961f28255Scgd * are met: 1061f28255Scgd * 1. Redistributions of source code must retain the above copyright 1161f28255Scgd * notice, this list of conditions and the following disclaimer. 1261f28255Scgd * 2. Redistributions in binary form must reproduce the above copyright 1361f28255Scgd * notice, this list of conditions and the following disclaimer in the 1461f28255Scgd * documentation and/or other materials provided with the distribution. 15e5aeb4eaSagc * 3. Neither the name of the University nor the names of its contributors 1661f28255Scgd * may be used to endorse or promote products derived from this software 1761f28255Scgd * without specific prior written permission. 1861f28255Scgd * 1961f28255Scgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2061f28255Scgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2161f28255Scgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2261f28255Scgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2361f28255Scgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2461f28255Scgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2561f28255Scgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2661f28255Scgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2761f28255Scgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2861f28255Scgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2961f28255Scgd * SUCH DAMAGE. 3061f28255Scgd */ 3161f28255Scgd 325ab1a671Slukem #include <sys/cdefs.h> 332fe2731dSlukem __COPYRIGHT("@(#) Copyright (c) 1988, 1993\ 342fe2731dSlukem The Regents of the University of California. All rights reserved."); 35*b76a7d7eSrillig /* @(#)morse.c 8.1 (Berkeley) 5/31/93 */ 36*b76a7d7eSrillig __RCSID("$NetBSD: morse.c,v 1.23 2024/10/12 19:26:24 rillig Exp $"); 3761f28255Scgd 3861f28255Scgd #include <ctype.h> 395ab1a671Slukem #include <stdio.h> 4032330650Smatt #include <stdlib.h> 41d5f8b67eShubertf #include <string.h> 425ab1a671Slukem #include <unistd.h> 4361f28255Scgd 44508549b5Srillig static const char digit[][6] = { 4561f28255Scgd "-----", 4661f28255Scgd ".----", 4761f28255Scgd "..---", 4861f28255Scgd "...--", 4961f28255Scgd "....-", 5061f28255Scgd ".....", 5161f28255Scgd "-....", 5261f28255Scgd "--...", 5361f28255Scgd "---..", 5461f28255Scgd "----.", 55508549b5Srillig }; 56508549b5Srillig 57508549b5Srillig static const char alph[][5] = { 5861f28255Scgd ".-", 5961f28255Scgd "-...", 6061f28255Scgd "-.-.", 6161f28255Scgd "-..", 6261f28255Scgd ".", 6361f28255Scgd "..-.", 6461f28255Scgd "--.", 6561f28255Scgd "....", 6661f28255Scgd "..", 6761f28255Scgd ".---", 6861f28255Scgd "-.-", 6961f28255Scgd ".-..", 7061f28255Scgd "--", 7161f28255Scgd "-.", 7261f28255Scgd "---", 7361f28255Scgd ".--.", 7461f28255Scgd "--.-", 7561f28255Scgd ".-.", 7661f28255Scgd "...", 7761f28255Scgd "-", 7861f28255Scgd "..-", 7961f28255Scgd "...-", 8061f28255Scgd ".--", 8161f28255Scgd "-..-", 8261f28255Scgd "-.--", 8361f28255Scgd "--..", 8461f28255Scgd }; 8561f28255Scgd 86*b76a7d7eSrillig static const struct { 871775f4feSjsm char c; 88508549b5Srillig const char morse[7]; 891775f4feSjsm } other[] = { 901775f4feSjsm { '.', ".-.-.-" }, 911775f4feSjsm { ',', "--..--" }, 921775f4feSjsm { ':', "---..." }, 931775f4feSjsm { '?', "..--.." }, 941775f4feSjsm { '\'', ".----." }, 951775f4feSjsm { '-', "-....-" }, 961775f4feSjsm { '/', "-..-." }, 971775f4feSjsm { '(', "-.--." }, 981775f4feSjsm { ')', "-.--.-" }, 991775f4feSjsm { '"', ".-..-." }, 1001775f4feSjsm { '=', "-...-" }, 1011775f4feSjsm { '+', ".-.-." }, 102a3e52c51Smaya { '_', "..--.-" }, 103cefbb2f3Smrg { '@', ".--.-." }, 104508549b5Srillig { '\0', "" } 1051775f4feSjsm }; 1061775f4feSjsm 107f2a20f5fSdholland static void morse(int); 108f2a20f5fSdholland static void decode(const char *); 109f2a20f5fSdholland static void show(const char *); 1105ab1a671Slukem 11161f28255Scgd static int sflag; 112d5f8b67eShubertf static int dflag; 11361f28255Scgd 1145ab1a671Slukem int 115277bd075Sdholland main(int argc, char **argv) 11661f28255Scgd { 1175ab1a671Slukem int ch; 1181775f4feSjsm char *p; 11961f28255Scgd 1205367f340Sjsm /* Revoke setgid privileges */ 121f9eca697Smycroft setgid(getgid()); 1225367f340Sjsm 123d5f8b67eShubertf while ((ch = getopt(argc, argv, "ds")) != -1) 12461f28255Scgd switch ((char)ch) { 125d5f8b67eShubertf case 'd': 126d5f8b67eShubertf dflag = 1; 127d5f8b67eShubertf break; 12861f28255Scgd case 's': 12961f28255Scgd sflag = 1; 13061f28255Scgd break; 13161f28255Scgd default: 132d5f8b67eShubertf fprintf(stderr, "usage: morse [-ds] [string ...]\n"); 13361f28255Scgd exit(1); 13461f28255Scgd } 13561f28255Scgd argc -= optind; 13661f28255Scgd argv += optind; 13761f28255Scgd 138d5f8b67eShubertf if (dflag) { 139d5f8b67eShubertf if (*argv) { 140d5f8b67eShubertf do { 141d5f8b67eShubertf decode(*argv); 142d5f8b67eShubertf } while (*++argv); 143d5f8b67eShubertf } else { 1441775f4feSjsm char foo[10]; /* All morse chars shorter than this */ 1450f032c1fSdholland int is_blank, i; 146d5f8b67eShubertf 1471775f4feSjsm i = 0; 1480f032c1fSdholland is_blank = 0; 1491775f4feSjsm while ((ch = getchar()) != EOF) { 1501775f4feSjsm if (ch == '-' || ch == '.') { 1511775f4feSjsm foo[i++] = ch; 1521775f4feSjsm if (i == 10) { 1531775f4feSjsm /* overrun means gibberish--print 'x' and 1541775f4feSjsm * advance */ 1551775f4feSjsm i = 0; 1561775f4feSjsm putchar('x'); 1571775f4feSjsm while ((ch = getchar()) != EOF && 1581775f4feSjsm (ch == '.' || ch == '-')) 1591775f4feSjsm ; 1600f032c1fSdholland is_blank = 1; 161d5f8b67eShubertf } 1621775f4feSjsm } else if (i) { 1631775f4feSjsm foo[i] = '\0'; 1641775f4feSjsm decode(foo); 1651775f4feSjsm i = 0; 1660f032c1fSdholland is_blank = 0; 1671775f4feSjsm } else if (isspace(ch)) { 1680f032c1fSdholland if (is_blank) { 1691775f4feSjsm /* print whitespace for each double blank */ 1701775f4feSjsm putchar(' '); 1710f032c1fSdholland is_blank = 0; 1721775f4feSjsm } else 1730f032c1fSdholland is_blank = 1; 174d5f8b67eShubertf } 175d5f8b67eShubertf } 176d5f8b67eShubertf } 177d5f8b67eShubertf putchar('\n'); 178d5f8b67eShubertf } else { 17961f28255Scgd if (*argv) 18061f28255Scgd do { 18161f28255Scgd for (p = *argv; *p; ++p) 18220cc95c1Srillig morse((unsigned char)*p); 1831775f4feSjsm show(""); 18461f28255Scgd } while (*++argv); 18561f28255Scgd else while ((ch = getchar()) != EOF) 18661f28255Scgd morse(ch); 1871775f4feSjsm show("...-.-"); /* SK */ 188d5f8b67eShubertf } 189d5f8b67eShubertf 190d5f8b67eShubertf return 0; 191d5f8b67eShubertf } 192d5f8b67eShubertf 193d5f8b67eShubertf void 194277bd075Sdholland decode(const char *s) 195d5f8b67eShubertf { 196*b76a7d7eSrillig for (size_t i = 0; i < __arraycount(digit); i++) 1971775f4feSjsm if (strcmp(digit[i], s) == 0) { 198d5f8b67eShubertf putchar('0' + i); 199d5f8b67eShubertf return; 200d5f8b67eShubertf } 201d5f8b67eShubertf 202*b76a7d7eSrillig for (size_t i = 0; i < __arraycount(alph); i++) 2031775f4feSjsm if (strcmp(alph[i], s) == 0) { 2041775f4feSjsm putchar('A' + i); 2051775f4feSjsm return; 206d5f8b67eShubertf } 207*b76a7d7eSrillig 208*b76a7d7eSrillig for (size_t i = 0; other[i].c; i++) 2091775f4feSjsm if (strcmp(other[i].morse, s) == 0) { 2101775f4feSjsm putchar(other[i].c); 2111775f4feSjsm return; 212d5f8b67eShubertf } 213*b76a7d7eSrillig 214*b76a7d7eSrillig if (strcmp("...-.-", s) == 0) /* SK */ 2151775f4feSjsm return; 216*b76a7d7eSrillig 2171775f4feSjsm putchar('x'); /* line noise */ 21861f28255Scgd } 21961f28255Scgd 2205ab1a671Slukem void 221277bd075Sdholland morse(int c) 22261f28255Scgd { 22361f28255Scgd if (isalpha(c)) 22461f28255Scgd show(alph[c - (isupper(c) ? 'A' : 'a')]); 22561f28255Scgd else if (isdigit(c)) 22661f28255Scgd show(digit[c - '0']); 22761f28255Scgd else if (isspace(c)) 2281775f4feSjsm show(""); /* could show BT for a pause */ 229*b76a7d7eSrillig else 230*b76a7d7eSrillig for (int i = 0; other[i].c; i++) 2311775f4feSjsm if (other[i].c == c) { 2321775f4feSjsm show(other[i].morse); 2331775f4feSjsm break; 2341775f4feSjsm } 23561f28255Scgd } 23661f28255Scgd 2375ab1a671Slukem void 238277bd075Sdholland show(const char *s) 23961f28255Scgd { 24061f28255Scgd if (sflag) 24161f28255Scgd printf(" %s", s); 24261f28255Scgd else for (; *s; ++s) 24361f28255Scgd printf(" %s", *s == '.' ? "dit" : "daw"); 2441775f4feSjsm printf("\n"); 24561f28255Scgd } 246