mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-27 03:11:52 +01:00
0b8224d1cc
We've ifdef'd out the copyright strings for some time now. Go ahead and remove the ifdefs. Plus whatever other detritis was left over from other recent removals. These copyright strings are present in the comments and are largely from CSRG's attempt at adding their copyright to every binary file (which modern interpretations of the license doesn't require). Sponsored by: Netflix
663 lines
15 KiB
C
663 lines
15 KiB
C
/*-
|
||
* Copyright (c) 1988, 1993
|
||
* The Regents of the University of California. All rights reserved.
|
||
*
|
||
* Redistribution and use in source and binary forms, with or without
|
||
* modification, are permitted provided that the following conditions
|
||
* are met:
|
||
* 1. Redistributions of source code must retain the above copyright
|
||
* notice, this list of conditions and the following disclaimer.
|
||
* 2. Redistributions in binary form must reproduce the above copyright
|
||
* notice, this list of conditions and the following disclaimer in the
|
||
* documentation and/or other materials provided with the distribution.
|
||
* 3. Neither the name of the University nor the names of its contributors
|
||
* may be used to endorse or promote products derived from this software
|
||
* without specific prior written permission.
|
||
*
|
||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||
* SUCH DAMAGE.
|
||
*/
|
||
|
||
/*
|
||
* Taught to send *real* morse by Lyndon Nerenberg (VE6BBM)
|
||
* <lyndon@orthanc.ca>
|
||
*/
|
||
|
||
#include <sys/time.h>
|
||
#include <sys/ioctl.h>
|
||
|
||
#include <ctype.h>
|
||
#include <err.h>
|
||
#include <fcntl.h>
|
||
#include <langinfo.h>
|
||
#include <locale.h>
|
||
#include <signal.h>
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <termios.h>
|
||
#include <unistd.h>
|
||
|
||
#ifdef __FreeBSD__
|
||
/* Always use the speaker, let the open fail if -p is selected */
|
||
#define SPEAKER "/dev/speaker"
|
||
#endif
|
||
|
||
#define WHITESPACE " \t\n"
|
||
#define DELIMITERS " \t"
|
||
|
||
#ifdef SPEAKER
|
||
#include <dev/speaker/speaker.h>
|
||
#endif
|
||
|
||
struct morsetab {
|
||
const char inchar;
|
||
const char *morse;
|
||
};
|
||
|
||
static const struct morsetab mtab[] = {
|
||
|
||
/* letters */
|
||
|
||
{'a', ".-"},
|
||
{'b', "-..."},
|
||
{'c', "-.-."},
|
||
{'d', "-.."},
|
||
{'e', "."},
|
||
{'f', "..-."},
|
||
{'g', "--."},
|
||
{'h', "...."},
|
||
{'i', ".."},
|
||
{'j', ".---"},
|
||
{'k', "-.-"},
|
||
{'l', ".-.."},
|
||
{'m', "--"},
|
||
{'n', "-."},
|
||
{'o', "---"},
|
||
{'p', ".--."},
|
||
{'q', "--.-"},
|
||
{'r', ".-."},
|
||
{'s', "..."},
|
||
{'t', "-"},
|
||
{'u', "..-"},
|
||
{'v', "...-"},
|
||
{'w', ".--"},
|
||
{'x', "-..-"},
|
||
{'y', "-.--"},
|
||
{'z', "--.."},
|
||
|
||
/* digits */
|
||
|
||
{'0', "-----"},
|
||
{'1', ".----"},
|
||
{'2', "..---"},
|
||
{'3', "...--"},
|
||
{'4', "....-"},
|
||
{'5', "....."},
|
||
{'6', "-...."},
|
||
{'7', "--..."},
|
||
{'8', "---.."},
|
||
{'9', "----."},
|
||
|
||
/* punctuation */
|
||
|
||
{',', "--..--"},
|
||
{'.', ".-.-.-"},
|
||
{'"', ".-..-."},
|
||
{'!', "..--."},
|
||
{'?', "..--.."},
|
||
{'/', "-..-."},
|
||
{'-', "-....-"},
|
||
{'=', "-...-"}, /* BT */
|
||
{':', "---..."},
|
||
{';', "-.-.-."},
|
||
{'(', "-.--."}, /* KN */
|
||
{')', "-.--.-"},
|
||
{'$', "...-..-"},
|
||
{'+', ".-.-."}, /* AR */
|
||
{'@', ".--.-."}, /* AC */
|
||
{'_', "..--.-"},
|
||
{'\'', ".----."},
|
||
|
||
/* prosigns without already assigned values */
|
||
|
||
{'#', ".-..."}, /* AS */
|
||
{'&', "...-.-"}, /* SK */
|
||
{'*', "...-."}, /* VE */
|
||
{'%', "-...-.-"}, /* BK */
|
||
|
||
{'\0', ""}
|
||
};
|
||
|
||
/*
|
||
* Code-points for some Latin1 chars in ISO-8859-1 encoding.
|
||
* UTF-8 encoded chars in the comments.
|
||
*/
|
||
static const struct morsetab iso8859_1tab[] = {
|
||
{'\340', ".--.-"}, /* à */
|
||
{'\341', ".--.-"}, /* á */
|
||
{'\342', ".--.-"}, /* â */
|
||
{'\344', ".-.-"}, /* ä */
|
||
{'\347', "-.-.."}, /* ç */
|
||
{'\350', "..-.."}, /* è */
|
||
{'\351', "..-.."}, /* é */
|
||
{'\352', "-..-."}, /* ê */
|
||
{'\361', "--.--"}, /* ñ */
|
||
{'\366', "---."}, /* ö */
|
||
{'\374', "..--"}, /* ü */
|
||
|
||
{'\0', ""}
|
||
};
|
||
|
||
/*
|
||
* Code-points for some Greek chars in ISO-8859-7 encoding.
|
||
* UTF-8 encoded chars in the comments.
|
||
*/
|
||
static const struct morsetab iso8859_7tab[] = {
|
||
/*
|
||
* This table does not implement:
|
||
* - the special sequences for the seven diphthongs,
|
||
* - the punctuation differences.
|
||
* Implementing these features would introduce too many
|
||
* special-cases in the program's main loop.
|
||
* The diphthong sequences are:
|
||
* alpha iota .-.-
|
||
* alpha upsilon ..--
|
||
* epsilon upsilon ---.
|
||
* eta upsilon ...-
|
||
* omicron iota ---..
|
||
* omicron upsilon ..-
|
||
* upsilon iota .---
|
||
* The different punctuation symbols are:
|
||
* ; ..-.-
|
||
* ! --..--
|
||
*/
|
||
{'\341', ".-"}, /* α, alpha */
|
||
{'\334', ".-"}, /* ά, alpha with acute */
|
||
{'\342', "-..."}, /* β, beta */
|
||
{'\343', "--."}, /* γ, gamma */
|
||
{'\344', "-.."}, /* δ, delta */
|
||
{'\345', "."}, /* ε, epsilon */
|
||
{'\335', "."}, /* έ, epsilon with acute */
|
||
{'\346', "--.."}, /* ζ, zeta */
|
||
{'\347', "...."}, /* η, eta */
|
||
{'\336', "...."}, /* ή, eta with acute */
|
||
{'\350', "-.-."}, /* θ, theta */
|
||
{'\351', ".."}, /* ι, iota */
|
||
{'\337', ".."}, /* ί, iota with acute */
|
||
{'\372', ".."}, /* ϊ, iota with diaeresis */
|
||
{'\300', ".."}, /* ΐ, iota with acute and diaeresis */
|
||
{'\352', "-.-"}, /* κ, kappa */
|
||
{'\353', ".-.."}, /* λ, lambda */
|
||
{'\354', "--"}, /* μ, mu */
|
||
{'\355', "-."}, /* ν, nu */
|
||
{'\356', "-..-"}, /* ξ, xi */
|
||
{'\357', "---"}, /* ο, omicron */
|
||
{'\374', "---"}, /* ό, omicron with acute */
|
||
{'\360', ".--."}, /* π, pi */
|
||
{'\361', ".-."}, /* ρ, rho */
|
||
{'\363', "..."}, /* σ, sigma */
|
||
{'\362', "..."}, /* ς, final sigma */
|
||
{'\364', "-"}, /* τ, tau */
|
||
{'\365', "-.--"}, /* υ, upsilon */
|
||
{'\375', "-.--"}, /* ύ, upsilon with acute */
|
||
{'\373', "-.--"}, /* ϋ, upsilon and diaeresis */
|
||
{'\340', "-.--"}, /* ΰ, upsilon with acute and diaeresis */
|
||
{'\366', "..-."}, /* φ, phi */
|
||
{'\367', "----"}, /* χ, chi */
|
||
{'\370', "--.-"}, /* ψ, psi */
|
||
{'\371', ".--"}, /* ω, omega */
|
||
{'\376', ".--"}, /* ώ, omega with acute */
|
||
|
||
{'\0', ""}
|
||
};
|
||
|
||
/*
|
||
* Code-points for the Cyrillic alphabet in KOI8-R encoding.
|
||
* UTF-8 encoded chars in the comments.
|
||
*/
|
||
static const struct morsetab koi8rtab[] = {
|
||
{'\301', ".-"}, /* а, a */
|
||
{'\302', "-..."}, /* б, be */
|
||
{'\327', ".--"}, /* в, ve */
|
||
{'\307', "--."}, /* г, ge */
|
||
{'\304', "-.."}, /* д, de */
|
||
{'\305', "."}, /* е, ye */
|
||
{'\243', "."}, /* ё, yo, the same as ye */
|
||
{'\326', "...-"}, /* ж, she */
|
||
{'\332', "--.."}, /* з, ze */
|
||
{'\311', ".."}, /* и, i */
|
||
{'\312', ".---"}, /* й, i kratkoye */
|
||
{'\313', "-.-"}, /* к, ka */
|
||
{'\314', ".-.."}, /* л, el */
|
||
{'\315', "--"}, /* м, em */
|
||
{'\316', "-."}, /* н, en */
|
||
{'\317', "---"}, /* о, o */
|
||
{'\320', ".--."}, /* п, pe */
|
||
{'\322', ".-."}, /* р, er */
|
||
{'\323', "..."}, /* с, es */
|
||
{'\324', "-"}, /* т, te */
|
||
{'\325', "..-"}, /* у, u */
|
||
{'\306', "..-."}, /* ф, ef */
|
||
{'\310', "...."}, /* х, kha */
|
||
{'\303', "-.-."}, /* ц, ce */
|
||
{'\336', "---."}, /* ч, che */
|
||
{'\333', "----"}, /* ш, sha */
|
||
{'\335', "--.-"}, /* щ, shcha */
|
||
{'\331', "-.--"}, /* ы, yi */
|
||
{'\330', "-..-"}, /* ь, myakhkij znak */
|
||
{'\334', "..-.."}, /* э, ae */
|
||
{'\300', "..--"}, /* ю, yu */
|
||
{'\321', ".-.-"}, /* я, ya */
|
||
|
||
{'\0', ""}
|
||
};
|
||
|
||
static void show(const char *), play(const char *), morse(char);
|
||
static void decode (char *), fdecode(FILE *);
|
||
static void ttyout(const char *);
|
||
static void sighandler(int);
|
||
|
||
static int pflag, lflag, rflag, sflag, eflag;
|
||
static int wpm = 20; /* effective words per minute */
|
||
static int cpm; /* effective words per minute between
|
||
* characters */
|
||
#define FREQUENCY 600
|
||
static int freq = FREQUENCY;
|
||
static char *device; /* for tty-controlled generator */
|
||
|
||
#define DASH_LEN 3
|
||
#define CHAR_SPACE 3
|
||
#define WORD_SPACE (7 - CHAR_SPACE - 1)
|
||
static float dot_clock;
|
||
static float cdot_clock;
|
||
static int spkr, line;
|
||
static struct termios otty, ntty;
|
||
static int olflags;
|
||
|
||
#ifdef SPEAKER
|
||
static tone_t sound;
|
||
#define GETOPTOPTS "c:d:ef:lprsw:"
|
||
#define USAGE \
|
||
"usage: morse [-elprs] [-d device] [-w speed] [-c speed] [-f frequency] [string ...]\n"
|
||
#else
|
||
#define GETOPTOPTS "c:d:ef:lrsw:"
|
||
#define USAGE \
|
||
"usage: morse [-elrs] [-d device] [-w speed] [-c speed] [-f frequency] [string ...]\n"
|
||
|
||
#endif
|
||
|
||
static const struct morsetab *hightab;
|
||
|
||
int
|
||
main(int argc, char *argv[])
|
||
{
|
||
int ch, lflags;
|
||
char *p, *codeset;
|
||
|
||
while ((ch = getopt(argc, argv, GETOPTOPTS)) != -1)
|
||
switch ((char) ch) {
|
||
case 'c':
|
||
cpm = atoi(optarg);
|
||
break;
|
||
case 'd':
|
||
device = optarg;
|
||
break;
|
||
case 'e':
|
||
eflag = 1;
|
||
setvbuf(stdout, 0, _IONBF, 0);
|
||
break;
|
||
case 'f':
|
||
freq = atoi(optarg);
|
||
break;
|
||
case 'l':
|
||
lflag = 1;
|
||
break;
|
||
#ifdef SPEAKER
|
||
case 'p':
|
||
pflag = 1;
|
||
break;
|
||
#endif
|
||
case 'r':
|
||
rflag = 1;
|
||
break;
|
||
case 's':
|
||
sflag = 1;
|
||
break;
|
||
case 'w':
|
||
wpm = atoi(optarg);
|
||
break;
|
||
case '?':
|
||
default:
|
||
errx(1, USAGE);
|
||
}
|
||
if ((sflag && lflag) || (sflag && rflag) || (lflag && rflag)) {
|
||
errx(1, "morse: only one of -l, -s, and -r allowed\n");
|
||
}
|
||
if ((pflag || device) && (sflag || lflag)) {
|
||
errx(1, "morse: only one of -p, -d and -l, -s allowed\n");
|
||
}
|
||
if (cpm == 0) {
|
||
cpm = wpm;
|
||
}
|
||
if ((pflag || device) && ((wpm < 1) || (wpm > 60) || (cpm < 1) || (cpm > 60))) {
|
||
errx(1, "morse: insane speed\n");
|
||
}
|
||
if ((pflag || device) && (freq == 0)) {
|
||
freq = FREQUENCY;
|
||
}
|
||
#ifdef SPEAKER
|
||
if (pflag) {
|
||
if ((spkr = open(SPEAKER, O_WRONLY, 0)) == -1) {
|
||
err(1, SPEAKER);
|
||
}
|
||
} else
|
||
#endif
|
||
if (device) {
|
||
if ((line = open(device, O_WRONLY | O_NONBLOCK)) == -1) {
|
||
err(1, "open tty line");
|
||
}
|
||
if (tcgetattr(line, &otty) == -1) {
|
||
err(1, "tcgetattr() failed");
|
||
}
|
||
ntty = otty;
|
||
ntty.c_cflag |= CLOCAL;
|
||
tcsetattr(line, TCSANOW, &ntty);
|
||
lflags = fcntl(line, F_GETFL);
|
||
lflags &= ~O_NONBLOCK;
|
||
fcntl(line, F_SETFL, &lflags);
|
||
ioctl(line, TIOCMGET, &lflags);
|
||
lflags &= ~TIOCM_RTS;
|
||
olflags = lflags;
|
||
ioctl(line, TIOCMSET, &lflags);
|
||
(void)signal(SIGHUP, sighandler);
|
||
(void)signal(SIGINT, sighandler);
|
||
(void)signal(SIGQUIT, sighandler);
|
||
(void)signal(SIGTERM, sighandler);
|
||
}
|
||
if (pflag || device) {
|
||
dot_clock = wpm / 2.4; /* dots/sec */
|
||
dot_clock = 1 / dot_clock; /* duration of a dot */
|
||
dot_clock = dot_clock / 2; /* dot_clock runs at twice */
|
||
/* the dot rate */
|
||
dot_clock = dot_clock * 100; /* scale for ioctl */
|
||
|
||
cdot_clock = cpm / 2.4; /* dots/sec */
|
||
cdot_clock = 1 / cdot_clock; /* duration of a dot */
|
||
cdot_clock = cdot_clock / 2; /* dot_clock runs at twice */
|
||
/* the dot rate */
|
||
cdot_clock = cdot_clock * 100; /* scale for ioctl */
|
||
}
|
||
|
||
argc -= optind;
|
||
argv += optind;
|
||
|
||
if (setlocale(LC_CTYPE, "") != NULL &&
|
||
*(codeset = nl_langinfo(CODESET)) != '\0') {
|
||
if (strcmp(codeset, "KOI8-R") == 0)
|
||
hightab = koi8rtab;
|
||
else if (strcmp(codeset, "ISO8859-1") == 0 ||
|
||
strcmp(codeset, "ISO8859-15") == 0)
|
||
hightab = iso8859_1tab;
|
||
else if (strcmp(codeset, "ISO8859-7") == 0)
|
||
hightab = iso8859_7tab;
|
||
}
|
||
|
||
if (lflag) {
|
||
printf("m");
|
||
}
|
||
if (rflag) {
|
||
if (*argv) {
|
||
do {
|
||
p = strtok(*argv, DELIMITERS);
|
||
if (p == NULL) {
|
||
decode(*argv);
|
||
}
|
||
else {
|
||
while (p) {
|
||
decode(p);
|
||
p = strtok(NULL, DELIMITERS);
|
||
}
|
||
}
|
||
} while (*++argv);
|
||
putchar('\n');
|
||
} else {
|
||
fdecode(stdin);
|
||
}
|
||
}
|
||
else if (*argv) {
|
||
do {
|
||
for (p = *argv; *p; ++p) {
|
||
if (eflag)
|
||
putchar(*p);
|
||
morse(*p);
|
||
}
|
||
if (eflag)
|
||
putchar(' ');
|
||
morse(' ');
|
||
} while (*++argv);
|
||
} else {
|
||
while ((ch = getchar()) != EOF) {
|
||
if (eflag)
|
||
putchar(ch);
|
||
morse(ch);
|
||
}
|
||
}
|
||
if (device)
|
||
tcsetattr(line, TCSANOW, &otty);
|
||
exit(0);
|
||
}
|
||
|
||
static void
|
||
morse(char c)
|
||
{
|
||
const struct morsetab *m;
|
||
|
||
if (isalpha((unsigned char)c))
|
||
c = tolower((unsigned char)c);
|
||
if ((c == '\r') || (c == '\n'))
|
||
c = ' ';
|
||
if (c == ' ') {
|
||
if (pflag)
|
||
play(" ");
|
||
else if (device)
|
||
ttyout(" ");
|
||
else if (lflag)
|
||
printf("\n");
|
||
else
|
||
show("");
|
||
return;
|
||
}
|
||
for (m = ((unsigned char)c < 0x80? mtab: hightab);
|
||
m != NULL && m->inchar != '\0';
|
||
m++) {
|
||
if (m->inchar == c) {
|
||
if (pflag) {
|
||
play(m->morse);
|
||
} else if (device) {
|
||
ttyout(m->morse);
|
||
} else
|
||
show(m->morse);
|
||
}
|
||
}
|
||
}
|
||
|
||
static void
|
||
show(const char *s)
|
||
{
|
||
if (lflag) {
|
||
printf("%s ", s);
|
||
} else if (sflag) {
|
||
printf(" %s\n", s);
|
||
} else {
|
||
for (; *s; ++s)
|
||
printf(" %s", *s == '.' ? *(s + 1) == '\0' ? "dit" :
|
||
"di" : "dah");
|
||
printf("\n");
|
||
}
|
||
}
|
||
|
||
static void
|
||
play(const char *s)
|
||
{
|
||
#ifdef SPEAKER
|
||
const char *c;
|
||
|
||
for (c = s; *c != '\0'; c++) {
|
||
switch (*c) {
|
||
case '.':
|
||
sound.frequency = freq;
|
||
sound.duration = dot_clock;
|
||
break;
|
||
case '-':
|
||
sound.frequency = freq;
|
||
sound.duration = dot_clock * DASH_LEN;
|
||
break;
|
||
case ' ':
|
||
sound.frequency = 0;
|
||
sound.duration = cdot_clock * WORD_SPACE;
|
||
break;
|
||
default:
|
||
sound.duration = 0;
|
||
}
|
||
if (sound.duration) {
|
||
if (ioctl(spkr, SPKRTONE, &sound) == -1) {
|
||
err(1, "ioctl play");
|
||
}
|
||
}
|
||
sound.frequency = 0;
|
||
sound.duration = dot_clock;
|
||
if (ioctl(spkr, SPKRTONE, &sound) == -1) {
|
||
err(1, "ioctl rest");
|
||
}
|
||
}
|
||
sound.frequency = 0;
|
||
sound.duration = cdot_clock * CHAR_SPACE;
|
||
ioctl(spkr, SPKRTONE, &sound);
|
||
#endif
|
||
}
|
||
|
||
static void
|
||
ttyout(const char *s)
|
||
{
|
||
const char *c;
|
||
int duration, on, lflags;
|
||
|
||
for (c = s; *c != '\0'; c++) {
|
||
switch (*c) {
|
||
case '.':
|
||
on = 1;
|
||
duration = dot_clock;
|
||
break;
|
||
case '-':
|
||
on = 1;
|
||
duration = dot_clock * DASH_LEN;
|
||
break;
|
||
case ' ':
|
||
on = 0;
|
||
duration = cdot_clock * WORD_SPACE;
|
||
break;
|
||
default:
|
||
on = 0;
|
||
duration = 0;
|
||
}
|
||
if (on) {
|
||
ioctl(line, TIOCMGET, &lflags);
|
||
lflags |= TIOCM_RTS;
|
||
ioctl(line, TIOCMSET, &lflags);
|
||
}
|
||
duration *= 10000;
|
||
if (duration)
|
||
usleep(duration);
|
||
ioctl(line, TIOCMGET, &lflags);
|
||
lflags &= ~TIOCM_RTS;
|
||
ioctl(line, TIOCMSET, &lflags);
|
||
duration = dot_clock * 10000;
|
||
usleep(duration);
|
||
}
|
||
duration = cdot_clock * CHAR_SPACE * 10000;
|
||
usleep(duration);
|
||
}
|
||
|
||
void
|
||
fdecode(FILE *stream)
|
||
{
|
||
char *n, *p, *s;
|
||
char buf[BUFSIZ];
|
||
|
||
s = buf;
|
||
while (fgets(s, BUFSIZ - (s - buf), stream)) {
|
||
p = buf;
|
||
|
||
while (*p && isblank(*p)) {
|
||
p++;
|
||
}
|
||
while (*p && isspace(*p)) {
|
||
p++;
|
||
putchar (' ');
|
||
}
|
||
while (*p) {
|
||
n = strpbrk(p, WHITESPACE);
|
||
if (n == NULL) {
|
||
/* The token was interrupted at the end
|
||
* of the buffer. Shift it to the begin
|
||
* of the buffer.
|
||
*/
|
||
for (s = buf; *p; *s++ = *p++)
|
||
;
|
||
} else {
|
||
*n = '\0';
|
||
n++;
|
||
decode(p);
|
||
p = n;
|
||
}
|
||
}
|
||
}
|
||
putchar('\n');
|
||
}
|
||
|
||
void
|
||
decode(char *p)
|
||
{
|
||
char c;
|
||
const struct morsetab *m;
|
||
|
||
c = ' ';
|
||
for (m = mtab; m != NULL && m->inchar != '\0'; m++) {
|
||
if (strcmp(m->morse, p) == 0) {
|
||
c = m->inchar;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (c == ' ')
|
||
for (m = hightab; m != NULL && m->inchar != '\0'; m++) {
|
||
if (strcmp(m->morse, p) == 0) {
|
||
c = m->inchar;
|
||
break;
|
||
}
|
||
}
|
||
|
||
putchar(c);
|
||
}
|
||
|
||
static void
|
||
sighandler(int signo)
|
||
{
|
||
|
||
ioctl(line, TIOCMSET, &olflags);
|
||
tcsetattr(line, TCSANOW, &otty);
|
||
|
||
signal(signo, SIG_DFL);
|
||
(void)kill(getpid(), signo);
|
||
}
|