1*6fa5e1daSmestre /* $OpenBSD: morse.c,v 1.22 2016/03/07 12:07:56 mestre Exp $ */
2df930be7Sderaadt
3df930be7Sderaadt /*
4df930be7Sderaadt * Copyright (c) 1988, 1993
5df930be7Sderaadt * The Regents of the University of California. All rights reserved.
6df930be7Sderaadt *
7df930be7Sderaadt * Redistribution and use in source and binary forms, with or without
8df930be7Sderaadt * modification, are permitted provided that the following conditions
9df930be7Sderaadt * are met:
10df930be7Sderaadt * 1. Redistributions of source code must retain the above copyright
11df930be7Sderaadt * notice, this list of conditions and the following disclaimer.
12df930be7Sderaadt * 2. Redistributions in binary form must reproduce the above copyright
13df930be7Sderaadt * notice, this list of conditions and the following disclaimer in the
14df930be7Sderaadt * documentation and/or other materials provided with the distribution.
157a09557bSmillert * 3. Neither the name of the University nor the names of its contributors
16df930be7Sderaadt * may be used to endorse or promote products derived from this software
17df930be7Sderaadt * without specific prior written permission.
18df930be7Sderaadt *
19df930be7Sderaadt * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20df930be7Sderaadt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21df930be7Sderaadt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22df930be7Sderaadt * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23df930be7Sderaadt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24df930be7Sderaadt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25df930be7Sderaadt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26df930be7Sderaadt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27df930be7Sderaadt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28df930be7Sderaadt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29df930be7Sderaadt * SUCH DAMAGE.
30df930be7Sderaadt */
31df930be7Sderaadt
32df930be7Sderaadt #include <ctype.h>
332010f3c8Smestre #include <err.h>
34d6778101Spjanzen #include <stdio.h>
3570ef01f6Sdavid #include <stdlib.h>
3670ef01f6Sdavid #include <string.h>
37d6778101Spjanzen #include <unistd.h>
38df930be7Sderaadt
39df930be7Sderaadt static char
40df930be7Sderaadt *digit[] = {
41df930be7Sderaadt "-----",
42df930be7Sderaadt ".----",
43df930be7Sderaadt "..---",
44df930be7Sderaadt "...--",
45df930be7Sderaadt "....-",
46df930be7Sderaadt ".....",
47df930be7Sderaadt "-....",
48df930be7Sderaadt "--...",
49df930be7Sderaadt "---..",
50df930be7Sderaadt "----.",
51df930be7Sderaadt },
52df930be7Sderaadt *alph[] = {
53df930be7Sderaadt ".-",
54df930be7Sderaadt "-...",
55df930be7Sderaadt "-.-.",
56df930be7Sderaadt "-..",
57df930be7Sderaadt ".",
58df930be7Sderaadt "..-.",
59df930be7Sderaadt "--.",
60df930be7Sderaadt "....",
61df930be7Sderaadt "..",
62df930be7Sderaadt ".---",
63df930be7Sderaadt "-.-",
64df930be7Sderaadt ".-..",
65df930be7Sderaadt "--",
66df930be7Sderaadt "-.",
67df930be7Sderaadt "---",
68df930be7Sderaadt ".--.",
69df930be7Sderaadt "--.-",
70df930be7Sderaadt ".-.",
71df930be7Sderaadt "...",
72df930be7Sderaadt "-",
73df930be7Sderaadt "..-",
74df930be7Sderaadt "...-",
75df930be7Sderaadt ".--",
76df930be7Sderaadt "-..-",
77df930be7Sderaadt "-.--",
78df930be7Sderaadt "--..",
79df930be7Sderaadt };
80df930be7Sderaadt
81c145bcadSpjanzen struct punc {
82c145bcadSpjanzen char c;
83c145bcadSpjanzen char *morse;
84c145bcadSpjanzen } other[] = {
85fa195fe7Ssthen { 'e', "..-.." }, /* accented e - only decodes */
86c145bcadSpjanzen { ',', "--..--" },
87c145bcadSpjanzen { '.', ".-.-.-" },
88c145bcadSpjanzen { '?', "..--.." },
89c145bcadSpjanzen { '/', "-..-." },
90c145bcadSpjanzen { '-', "-....-" },
91c145bcadSpjanzen { ':', "---..." },
92c145bcadSpjanzen { ';', "-.-.-." },
93fa195fe7Ssthen { '(', "-.--." }, /* KN */
940de85c04Ssthen { ')', "-.--.-" },
95c145bcadSpjanzen { '"', ".-..-." },
96c145bcadSpjanzen { '`', ".-..-." },
97c145bcadSpjanzen { '\'', ".----." },
98fa195fe7Ssthen { '+', ".-.-." }, /* AR \n\n\n */
99fa195fe7Ssthen { '=', "-...-" }, /* BT \n\n */
100fa195fe7Ssthen { '@', ".--.-." },
101fa195fe7Ssthen { '\n', ".-.-" }, /* AA (will only decode) */
102c145bcadSpjanzen { '\0', NULL }
103c145bcadSpjanzen };
104c145bcadSpjanzen
105fa195fe7Ssthen struct prosign {
106fa195fe7Ssthen char *c;
107fa195fe7Ssthen char *morse;
108fa195fe7Ssthen } ps[] = {
109fa195fe7Ssthen { "<AS>", ".-..." }, /* wait */
110fa195fe7Ssthen { "<CL>", "-.-..-.." },
111fa195fe7Ssthen { "<CT>", "-.-.-" }, /* start */
112fa195fe7Ssthen { "<EE5>", "......" }, /* error */
113fa195fe7Ssthen { "<EE5>", "......." },
114fa195fe7Ssthen { "<EE5>", "........" },
115fa195fe7Ssthen { "<SK>", "...-.-" },
116fa195fe7Ssthen { "<SN>", "...-." }, /* understood */
117fa195fe7Ssthen { "<SOS>", "...---..." },
118fa195fe7Ssthen { NULL, NULL }
119fa195fe7Ssthen };
120fa195fe7Ssthen
121c72b5b24Smillert void morse(int);
122c72b5b24Smillert void decode(char *);
123c72b5b24Smillert void show(char *);
124df930be7Sderaadt
125d6778101Spjanzen static int sflag = 0;
126c145bcadSpjanzen static int dflag = 0;
127d6778101Spjanzen
128d6778101Spjanzen int
main(int argc,char * argv[])129ff8320a7Sderaadt main(int argc, char *argv[])
130df930be7Sderaadt {
131d6778101Spjanzen int ch;
132d6778101Spjanzen char *p;
133df930be7Sderaadt
134673e924cSdoug if (pledge("stdio", NULL) == -1)
135673e924cSdoug err(1, "pledge");
136673e924cSdoug
137c145bcadSpjanzen while ((ch = getopt(argc, argv, "dsh")) != -1)
1385195d91eSokan switch(ch) {
139c145bcadSpjanzen case 'd':
140c145bcadSpjanzen dflag = 1;
141c145bcadSpjanzen break;
142df930be7Sderaadt case 's':
143df930be7Sderaadt sflag = 1;
144df930be7Sderaadt break;
145*6fa5e1daSmestre case 'h':
146df930be7Sderaadt default:
147*6fa5e1daSmestre fprintf(stderr, "usage: %s [-d | -s] [string ...]\n",
148*6fa5e1daSmestre getprogname());
14917641e31Stb return 1;
150df930be7Sderaadt }
151df930be7Sderaadt argc -= optind;
152df930be7Sderaadt argv += optind;
153df930be7Sderaadt
154c145bcadSpjanzen if (dflag) {
155c145bcadSpjanzen if (*argv) {
156c145bcadSpjanzen do {
157c145bcadSpjanzen decode(*argv);
158c145bcadSpjanzen } while (*++argv);
159c145bcadSpjanzen } else {
160c145bcadSpjanzen char foo[10]; /* All morse chars shorter than this */
161c145bcadSpjanzen int isblank, i;
162c145bcadSpjanzen
163c145bcadSpjanzen i = 0;
164c145bcadSpjanzen isblank = 0;
165c145bcadSpjanzen while ((ch = getchar()) != EOF) {
166c145bcadSpjanzen if (ch == '-' || ch == '.') {
167c145bcadSpjanzen foo[i++] = ch;
168c145bcadSpjanzen if (i == 10) {
169c145bcadSpjanzen /* overrun means gibberish--print 'x' and
170c145bcadSpjanzen * advance */
171c145bcadSpjanzen i = 0;
172c145bcadSpjanzen putchar('x');
173c145bcadSpjanzen while ((ch = getchar()) != EOF &&
174c145bcadSpjanzen (ch == '.' || ch == '-'))
175c145bcadSpjanzen ;
176c145bcadSpjanzen isblank = 1;
177c145bcadSpjanzen }
178c145bcadSpjanzen } else if (i) {
179c145bcadSpjanzen foo[i] = '\0';
180c145bcadSpjanzen decode(foo);
181c145bcadSpjanzen i = 0;
182c145bcadSpjanzen isblank = 0;
183c145bcadSpjanzen } else if (isspace(ch)) {
184c145bcadSpjanzen if (isblank) {
185c145bcadSpjanzen /* print whitespace for each double blank */
186c145bcadSpjanzen putchar(' ');
187c145bcadSpjanzen isblank = 0;
188c145bcadSpjanzen } else
189c145bcadSpjanzen isblank = 1;
190c145bcadSpjanzen }
191c145bcadSpjanzen }
192c145bcadSpjanzen }
193c145bcadSpjanzen putchar('\n');
194c145bcadSpjanzen } else {
195df930be7Sderaadt if (*argv)
196df930be7Sderaadt do {
197df930be7Sderaadt for (p = *argv; *p; ++p)
198df930be7Sderaadt morse((int)*p);
199d6778101Spjanzen show("");
200df930be7Sderaadt } while (*++argv);
201df930be7Sderaadt else while ((ch = getchar()) != EOF)
202df930be7Sderaadt morse(ch);
203d6778101Spjanzen show("...-.-"); /* SK */
204c145bcadSpjanzen }
20517641e31Stb return 0;
206df930be7Sderaadt }
207df930be7Sderaadt
208d6778101Spjanzen void
morse(int c)209ff8320a7Sderaadt morse(int c)
210df930be7Sderaadt {
211c145bcadSpjanzen int i;
212c145bcadSpjanzen
213df930be7Sderaadt if (isalpha(c))
214df930be7Sderaadt show(alph[c - (isupper(c) ? 'A' : 'a')]);
215df930be7Sderaadt else if (isdigit(c))
216df930be7Sderaadt show(digit[c - '0']);
217df930be7Sderaadt else if (isspace(c))
218d6778101Spjanzen show(""); /* could show BT for a pause */
219c145bcadSpjanzen else {
220c145bcadSpjanzen i = 0;
221c145bcadSpjanzen while (other[i].c) {
222c145bcadSpjanzen if (other[i].c == c) {
223c145bcadSpjanzen show(other[i].morse);
224d6778101Spjanzen break;
225d6778101Spjanzen }
226c145bcadSpjanzen i++;
227df930be7Sderaadt }
228c145bcadSpjanzen }
229c145bcadSpjanzen }
230c145bcadSpjanzen
231c145bcadSpjanzen void
decode(char * s)232ff8320a7Sderaadt decode(char *s)
233c145bcadSpjanzen {
234c145bcadSpjanzen int i;
235c145bcadSpjanzen
236c145bcadSpjanzen for (i = 0; i < 10; i++)
237c145bcadSpjanzen if (strcmp(digit[i], s) == 0) {
238c145bcadSpjanzen putchar('0' + i);
239c145bcadSpjanzen return;
240c145bcadSpjanzen }
241c145bcadSpjanzen
242c145bcadSpjanzen for (i = 0; i < 26; i++)
243c145bcadSpjanzen if (strcmp(alph[i], s) == 0) {
244c145bcadSpjanzen putchar('A' + i);
245c145bcadSpjanzen return;
246c145bcadSpjanzen }
247c145bcadSpjanzen i = 0;
248c145bcadSpjanzen while (other[i].c) {
249c145bcadSpjanzen if (strcmp(other[i].morse, s) == 0) {
250c145bcadSpjanzen putchar(other[i].c);
251c145bcadSpjanzen return;
252c145bcadSpjanzen }
253c145bcadSpjanzen i++;
254c145bcadSpjanzen }
255fa195fe7Ssthen i = 0;
256fa195fe7Ssthen while (ps[i].c) {
257fa195fe7Ssthen /* put whitespace around prosigns */
258fa195fe7Ssthen if (strcmp(ps[i].morse, s) == 0) {
259fa195fe7Ssthen printf(" %s ", ps[i].c);
260fa195fe7Ssthen return;
261fa195fe7Ssthen }
262fa195fe7Ssthen i++;
263fa195fe7Ssthen }
264c145bcadSpjanzen putchar('x'); /* line noise */
265c145bcadSpjanzen }
266c145bcadSpjanzen
267c145bcadSpjanzen
268df930be7Sderaadt
269d6778101Spjanzen void
show(char * s)270ff8320a7Sderaadt show(char *s)
271df930be7Sderaadt {
272df930be7Sderaadt if (sflag)
273df930be7Sderaadt printf(" %s", s);
274df930be7Sderaadt else for (; *s; ++s)
275df930be7Sderaadt printf(" %s", *s == '.' ? "dit" : "daw");
276d6778101Spjanzen printf("\n");
277df930be7Sderaadt }
278