diff options
| author | Colin Percival <cperciva@FreeBSD.org> | 2015-10-02 10:08:11 +0000 |
|---|---|---|
| committer | Colin Percival <cperciva@FreeBSD.org> | 2015-10-02 10:08:11 +0000 |
| commit | 6ae1554a5d9b318f8ad53ccc39fa5a961403da73 (patch) | |
| tree | 0bbcb3f392def57bae56978c0da09362f7d6b426 /usr.bin/morse | |
| parent | d58b610faa4552666982078efafd542171304865 (diff) | |
Notes
Diffstat (limited to 'usr.bin/morse')
| -rw-r--r-- | usr.bin/morse/Makefile | 7 | ||||
| -rw-r--r-- | usr.bin/morse/Makefile.depend | 18 | ||||
| -rw-r--r-- | usr.bin/morse/morse.6 | 197 | ||||
| -rw-r--r-- | usr.bin/morse/morse.c | 589 |
4 files changed, 811 insertions, 0 deletions
diff --git a/usr.bin/morse/Makefile b/usr.bin/morse/Makefile new file mode 100644 index 000000000000..443542293777 --- /dev/null +++ b/usr.bin/morse/Makefile @@ -0,0 +1,7 @@ +# @(#)Makefile 8.1 (Berkeley) 5/31/93 +# $FreeBSD$ + +PROG= morse +MAN= morse.6 + +.include <bsd.prog.mk> diff --git a/usr.bin/morse/Makefile.depend b/usr.bin/morse/Makefile.depend new file mode 100644 index 000000000000..3646e2e2b1af --- /dev/null +++ b/usr.bin/morse/Makefile.depend @@ -0,0 +1,18 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + gnu/lib/csu \ + gnu/lib/libgcc \ + include \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/libc \ + lib/libcompiler_rt \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.bin/morse/morse.6 b/usr.bin/morse/morse.6 new file mode 100644 index 000000000000..94645bbf5c7f --- /dev/null +++ b/usr.bin/morse/morse.6 @@ -0,0 +1,197 @@ +.\" Copyright (c) 2000 Alexey Zelkin. All rights reserved. +.\" Copyright (c) 1988, 1991, 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. +.\" +.\" @(#)bcd.6 8.1 (Berkeley) 5/31/93 +.\" $FreeBSD$ +.\" +.Dd June 7, 2005 +.Dt MORSE 6 +.Os +.Sh NAME +.Nm morse +.Nd reformat input as morse code +.Sh SYNOPSIS +.Nm +.Op Fl elps +.Op Fl d Ar device +.Op Fl w Ar speed +.Op Fl c Ar speed +.Op Fl f Ar frequency +.Op Ar string ... +.Sh DESCRIPTION +The +.Nm +command reads the given input and reformats it in the form of morse code. +Acceptable input are command line arguments or the standard input. +.Pp +Available options: +.Bl -tag -width indent +.It Fl l +The +.Fl l +option produces output suitable for +.Xr led 4 +devices. +.It Fl s +The +.Fl s +option produces dots and dashes rather than words. +.It Fl p +Send morse the real way. +This only works if your system has +.Xr speaker 4 +support. +.It Fl w Ar speed +Set the sending speed in words per minute. +If not specified, the default +speed of 20 WPM is used. +.It Fl c Ar speed +Farnsworth support. +Set the spacing between characters in words per minute. +This is independent of the speed +that the individual characters are sent. +If not specified, defaults to the effective value of the +.Fl w +option. +.It Fl f Ar frequency +Set the sidetone frequency to something other than the default 600 Hz. +.It Fl d Ar device +Similar to +.Fl p , +but use the RTS line of +.Ar device +(which must by a TTY device) +in order to emit the morse code. +.It Fl e +Echo each character before it is sent, used together with either +.Fl p +or +.Fl d . +.El +.Pp +The +.Fl w , c +and +.Fl f +flags only work in conjunction with either the +.Fl p +or the +.Fl d +flag. +.Pp +Not all prosigns have corresponding characters. +Use +.Ql # +for +.Em AS , +.Ql & +for +.Em SK , +.Ql * +for +.Em VE +and +.Ql % +for +.Em BK . +The more common prosigns are +.Ql = +for +.Em BT , +.Ql \&( +for +.Em KN +and +.Ql + +for +.Em AR . +.Pp +Using the +.Fl d +flag, +it is possible to key an external device, like a sidetone generator with +a headset for training purposes, or even your ham radio transceiver. +For +the latter, simply connect an NPN transistor to the serial port +.Ar device , +emitter connected to ground, base connected through a resistor +(few kiloohms) to RTS, collector to the key line of your transceiver +(assuming the transceiver has a positive key supply voltage and is keyed +by grounding the key input line). +A capacitor (some nanofarads) between +base and ground is advisable to keep stray RF away, +and to suppress the +minor glitch that is generated during program startup. +.Sh ENVIRONMENT +Your +.Ev LC_CTYPE +locale codeset determines how +characters with the high-order bit set +are interpreted. +.Pp +.Bl -tag -width ".Li ISO8859-15" -compact +.It Li ISO8859-1 +.It Li ISO8859-15 +Interpret characters with the high-order bit set as Western European characters. +.Pp +.It Li KOI8-R +Interpret characters with the high-order bit set as Cyrillic characters. +.Pp +.It Li ISO8859-7 +Interpret characters with the high-order bit set as Greek characters. +.El +.Sh FILES +.Bl -tag -width ".Pa /dev/speaker" -compact +.It Pa /dev/speaker +.Xr speaker 4 +device file +.El +.Sh SEE ALSO +.Xr speaker 4 +.Sh HISTORY +Sound support for +.Nm +added by +.An Lyndon Nerenberg (VE6BBM) Aq Mt lyndon@orthanc.ca . +.Pp +Ability to key an external device added by +.An J\(:org Wunsch +(DL8DTL). +.Pp +Farnsworth support for +.Nm +added by +.An Stephen Cravey (N5UUU). +.Sh BUGS +Only understands a few European characters +(German and French), +no Asian characters, +and no continental landline code. +.Pp +Sends a bit slower than it should due to system overhead. +Some people would call this a feature. diff --git a/usr.bin/morse/morse.c b/usr.bin/morse/morse.c new file mode 100644 index 000000000000..03a09a6cb530 --- /dev/null +++ b/usr.bin/morse/morse.c @@ -0,0 +1,589 @@ +/* + * 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> + */ + +#ifndef lint +static const char copyright[] = +"@(#) Copyright (c) 1988, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +#if 0 +static char sccsid[] = "@(#)morse.c 8.1 (Berkeley) 5/31/93"; +#endif +static const char rcsid[] = + "$FreeBSD$"; +#endif /* not lint */ + +#include <sys/time.h> + +#include <ctype.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> + +/* Always use the speaker, let the open fail if -p is selected */ +#define SPEAKER "/dev/speaker" + +#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', "-..-."}, /* ê */ + {'\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 ttyout(const char *); +static void sighandler(int); + +#define GETOPTOPTS "c:d:ef:lsw:" +#define USAGE \ +"usage: morse [-els] [-d device] [-w speed] [-c speed] [-f frequency] [string ...]\n" + +static int pflag, lflag, 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; +#undef GETOPTOPTS +#define GETOPTOPTS "c:d:ef:lpsw:" +#undef USAGE +#define USAGE \ +"usage: morse [-elps] [-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 's': + sflag = 1; + break; + case 'w': + wpm = atoi(optarg); + break; + case '?': + default: + fputs(USAGE, stderr); + exit(1); + } + if (sflag && lflag) { + fputs("morse: only one of -l and -s allowed\n", stderr); + exit(1); + } + if ((pflag || device) && (sflag || lflag)) { + fputs("morse: only one of -p, -d and -l, -s allowed\n", stderr); + exit(1); + } + if (cpm == 0) + cpm = wpm; + if ((pflag || device) && ((wpm < 1) || (wpm > 60) || (cpm < 1) || (cpm > 60))) { + fputs("morse: insane speed\n", stderr); + exit(1); + } + if ((pflag || device) && (freq == 0)) + freq = FREQUENCY; + +#ifdef SPEAKER + if (pflag) { + if ((spkr = open(SPEAKER, O_WRONLY, 0)) == -1) { + perror(SPEAKER); + exit(1); + } + } else +#endif + if (device) { + if ((line = open(device, O_WRONLY | O_NONBLOCK)) == -1) { + perror("open tty line"); + exit(1); + } + if (tcgetattr(line, &otty) == -1) { + perror("tcgetattr() failed"); + exit(1); + } + 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 (*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) { + perror("ioctl play"); + exit(1); + } + } + sound.frequency = 0; + sound.duration = dot_clock; + if (ioctl(spkr, SPKRTONE, &sound) == -1) { + perror("ioctl rest"); + exit(1); + } + } + 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); +} + +static void +sighandler(int signo) +{ + + ioctl(line, TIOCMSET, &olflags); + tcsetattr(line, TCSANOW, &otty); + + signal(signo, SIG_DFL); + (void)kill(getpid(), signo); +} |
