morse.c revision 147110
11722Sjkh/* 21722Sjkh * Copyright (c) 1988, 1993 31722Sjkh * The Regents of the University of California. All rights reserved. 41722Sjkh * 51722Sjkh * Redistribution and use in source and binary forms, with or without 61722Sjkh * modification, are permitted provided that the following conditions 71722Sjkh * are met: 81722Sjkh * 1. Redistributions of source code must retain the above copyright 91722Sjkh * notice, this list of conditions and the following disclaimer. 101722Sjkh * 2. Redistributions in binary form must reproduce the above copyright 111722Sjkh * notice, this list of conditions and the following disclaimer in the 121722Sjkh * documentation and/or other materials provided with the distribution. 131722Sjkh * 3. All advertising materials mentioning features or use of this software 141722Sjkh * must display the following acknowledgement: 151722Sjkh * This product includes software developed by the University of 161722Sjkh * California, Berkeley and its contributors. 171722Sjkh * 4. Neither the name of the University nor the names of its contributors 181722Sjkh * may be used to endorse or promote products derived from this software 191722Sjkh * without specific prior written permission. 201722Sjkh * 211722Sjkh * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221722Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231722Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241722Sjkh * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2556995Sluigi * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2656995Sluigi * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271722Sjkh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281722Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291722Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301722Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311722Sjkh * SUCH DAMAGE. 321722Sjkh */ 338857Srgrimes 341722Sjkh/* 3570884Sjoe * Taught to send *real* morse by Lyndon Nerenberg (VE7TCP/VE6BBM) 3670884Sjoe * <lyndon@orthanc.com> 3770884Sjoe */ 3870884Sjoe 3929453Scharnier#ifndef lint 4029453Scharnierstatic const char copyright[] = 4170124Sjoe"@(#) Copyright (c) 1988, 1993\n\ 4229453Scharnier The Regents of the University of California. All rights reserved.\n"; 431722Sjkh#endif /* not lint */ 4429453Scharnier 451722Sjkh#ifndef lint 461722Sjkh#if 0 471722Sjkhstatic char sccsid[] = "@(#)morse.c 8.1 (Berkeley) 5/31/93"; 481722Sjkh#endif 491722Sjkhstatic const char rcsid[] = 501722Sjkh "$FreeBSD: head/games/morse/morse.c 147110 2005-06-07 19:01:41Z joerg $"; 511722Sjkh#endif /* not lint */ 521722Sjkh 531722Sjkh#include <sys/time.h> 541722Sjkh 551722Sjkh#include <ctype.h> 561722Sjkh#include <fcntl.h> 571722Sjkh#include <langinfo.h> 5870884Sjoe#include <locale.h> 5970884Sjoe#include <signal.h> 601722Sjkh#include <stdio.h> 611722Sjkh#include <stdlib.h> 621722Sjkh#include <string.h> 631722Sjkh#include <termios.h> 641722Sjkh#include <unistd.h> 6570884Sjoe 6670884Sjoe#ifdef SPEAKER 6770884Sjoe#include <machine/speaker.h> 6870884Sjoe#endif 6970884Sjoe 7070884Sjoestruct morsetab { 7170884Sjoe char inchar; 7270884Sjoe char *morse; 7370884Sjoe}; 7470884Sjoe 7570884Sjoestatic const struct morsetab mtab[] = { 7693435Sluigi 77153687Sceri /* letters */ 7870884Sjoe 791722Sjkh {'a', ".-"}, 801722Sjkh {'b', "-..."}, 811722Sjkh {'c', "-.-."}, 821722Sjkh {'d', "-.."}, 831722Sjkh {'e', "."}, 8468750Sjoe {'f', "..-."}, 8570884Sjoe {'g', "--."}, 8670884Sjoe {'h', "...."}, 87153687Sceri {'i', ".."}, 8870884Sjoe {'j', ".---"}, 891722Sjkh {'k', "-.-"}, 901722Sjkh {'l', ".-.."}, 911722Sjkh {'m', "--"}, 921722Sjkh {'n', "-."}, 9370884Sjoe {'o', "---"}, 9470884Sjoe {'p', ".--."}, 951722Sjkh {'q', "--.-"}, 961722Sjkh {'r', ".-."}, 971722Sjkh {'s', "..."}, 9870884Sjoe {'t', "-"}, 991722Sjkh {'u', "..-"}, 10070884Sjoe {'v', "...-"}, 1011722Sjkh {'w', ".--"}, 1026696Sphk {'x', "-..-"}, 1036696Sphk {'y', "-.--"}, 1041722Sjkh {'z', "--.."}, 1051722Sjkh 1061722Sjkh /* digits */ 1071722Sjkh 1081722Sjkh {'0', "-----"}, 1091722Sjkh {'1', ".----"}, 1101722Sjkh {'2', "..---"}, 111153687Sceri {'3', "...--"}, 112153687Sceri {'4', "....-"}, 1131722Sjkh {'5', "....."}, 1141722Sjkh {'6', "-...."}, 1151722Sjkh {'7', "--..."}, 1168857Srgrimes {'8', "---.."}, 1171722Sjkh {'9', "----."}, 1181722Sjkh 1191722Sjkh /* punctuation */ 1201722Sjkh 1211722Sjkh {',', "--..--"}, 1221722Sjkh {'.', ".-.-.-"}, 12370884Sjoe {'"', ".-..-."}, 12470884Sjoe {'!', "..--."}, 1251722Sjkh {'?', "..--.."}, 12670884Sjoe {'/', "-..-."}, 12770884Sjoe {'-', "-....-"}, 12870884Sjoe {'=', "-...-"}, /* BT */ 1298857Srgrimes {':', "---..."}, 13070884Sjoe {';', "-.-.-."}, 13170884Sjoe {'(', "-.--."}, /* KN */ 13270884Sjoe {')', "-.--.-"}, 13370884Sjoe {'$', "...-..-"}, 13470884Sjoe {'+', ".-.-."}, /* AR */ 13570884Sjoe {'@', ".--.-."}, /* AC */ 13669413Sluigi 13770884Sjoe /* prosigns without already assigned values */ 13870884Sjoe 13970884Sjoe {'#', ".-..."}, /* AS */ 14070884Sjoe {'&', "...-.-"}, /* SK */ 14170884Sjoe {'*', "...-."}, /* VE */ 14270884Sjoe {'%', "-...-.-"}, /* BK */ 14370884Sjoe 14470884Sjoe {'\0', ""} 14570884Sjoe}; 14670884Sjoe 14770884Sjoe 1481722Sjkhstatic const struct morsetab iso8859_1tab[] = { 14970884Sjoe {'�', ".--.-"}, 15070884Sjoe {'�', ".--.-"}, 15170884Sjoe {'�', ".--.-"}, 15270884Sjoe {'�', ".-.-"}, 15370884Sjoe {'�', "-.-.."}, 15470113Sjoe {'�', "..-.."}, 15570113Sjoe {'�', "..-.."}, 1561722Sjkh {'�', "-..-."}, 15770884Sjoe {'�', "---."}, 15870884Sjoe {'�', "..--"}, 15970884Sjoe 16070884Sjoe {'\0', ""} 16170884Sjoe}; 16270884Sjoe 16370884Sjoestatic const struct morsetab iso8859_7tab[] = { 16470884Sjoe /* 16570884Sjoe * The greek alphabet; you'll need an 8859-7 font in order 16670884Sjoe * to see the actual characters. 16770884Sjoe * This table does not implement: 16870884Sjoe * - the special sequences for the seven diphthongs, 16970884Sjoe * - the punctuation differences. 17070884Sjoe * Implementing these features would introduce too many 17170884Sjoe * special-cases in the program's main loop. 17270884Sjoe * The diphtong sequences are: 17370884Sjoe * alpha iota .-.- 17470884Sjoe * alpha upsilon ..-- 17570884Sjoe * epsilon upsilon ---. 1761722Sjkh * eta upsilon ...- 1771722Sjkh * omikron iota ---.. 17870884Sjoe * omikron upsilon ..- 17970884Sjoe * upsilon iota .--- 1801722Sjkh * The different punctuation symbols are: 18170884Sjoe * ; ..-.- 18270884Sjoe * ! --..-- 1831722Sjkh */ 18470884Sjoe {'�', ".-"}, /* alpha */ 18570884Sjoe {'�', ".-"}, /* alpha with acute */ 18670884Sjoe {'�', "-..."}, /* beta */ 1871722Sjkh {'�', "--."}, /* gamma */ 18870884Sjoe {'�', "-.."}, /* delta */ 1891722Sjkh {'�', "."}, /* epsilon */ 19070884Sjoe {'�', "."}, /* epsilon with acute */ 1911722Sjkh {'�', "--.."}, /* zeta */ 19270884Sjoe {'�', "...."}, /* eta */ 19370884Sjoe {'�', "...."}, /* eta with acute */ 19470884Sjoe {'�', "-.-."}, /* theta */ 19570884Sjoe {'�', ".."}, /* iota */ 1961722Sjkh {'�', ".."}, /* iota with acute */ 19770884Sjoe {'�', ".."}, /* iota with diairesis */ 19870884Sjoe {'�', ".."}, /* iota with acute and diairesis */ 1991722Sjkh {'�', "-.-"}, /* kappa */ 20070884Sjoe {'�', ".-.."}, /* lamda */ 20170884Sjoe {'�', "--"}, /* mu */ 20270884Sjoe {'�', "-."}, /* nu */ 20370884Sjoe {'�', "-..-"}, /* xi */ 20470884Sjoe {'�', "---"}, /* omicron */ 20570884Sjoe {'�', "---"}, /* omicron with acute */ 20670884Sjoe {'�', ".--."}, /* pi */ 20770884Sjoe {'�', ".-."}, /* rho */ 20870884Sjoe {'�', "..."}, /* sigma */ 20970124Sjoe {'�', "..."}, /* final sigma */ 2101722Sjkh {'�', "-"}, /* tau */ 21170884Sjoe {'�', "-.--"}, /* upsilon */ 21270884Sjoe {'�', "-.--"}, /* upsilon with acute */ 21370884Sjoe {'�', "-.--"}, /* upsilon and diairesis */ 2146696Sphk {'�', "-.--"}, /* upsilon with acute and diairesis */ 21570884Sjoe {'�', "..-."}, /* phi */ 2161722Sjkh {'�', "----"}, /* chi */ 21770884Sjoe {'�', "--.-"}, /* psi */ 2181722Sjkh {'�', ".--"}, /* omega */ 2191722Sjkh {'�', ".--"}, /* omega with acute */ 2201722Sjkh 2211722Sjkh {'\0', ""} 2221722Sjkh}; 22370884Sjoe 22470884Sjoestatic const struct morsetab koi8rtab[] = { 22570884Sjoe /* 22670884Sjoe * the cyrillic alphabet; you'll need a KOI8R font in order 22770884Sjoe * to see the actual characters 2281722Sjkh */ 2291722Sjkh {'�', ".-"}, /* a */ 2301722Sjkh {'�', "-..."}, /* be */ 2311722Sjkh {'�', ".--"}, /* ve */ 2321722Sjkh {'�', "--."}, /* ge */ 2331722Sjkh {'�', "-.."}, /* de */ 2341722Sjkh {'�', "."}, /* ye */ 2351722Sjkh {'�', "."}, /* yo, the same as ye */ 2361722Sjkh {'�', "...-"}, /* she */ 2371722Sjkh {'�', "--.."}, /* ze */ 2381722Sjkh {'�', ".."}, /* i */ 2391722Sjkh {'�', ".---"}, /* i kratkoye */ 2408857Srgrimes {'�', "-.-"}, /* ka */ 2411722Sjkh {'�', ".-.."}, /* el */ 2421722Sjkh {'�', "--"}, /* em */ 2431722Sjkh {'�', "-."}, /* en */ 2441722Sjkh {'�', "---"}, /* o */ 245153687Sceri {'�', ".--."}, /* pe */ 24668750Sjoe {'�', ".-."}, /* er */ 2471722Sjkh {'�', "..."}, /* es */ 2481722Sjkh {'�', "-"}, /* te */ 2491722Sjkh {'�', "..-"}, /* u */ 2501722Sjkh {'�', "..-."}, /* ef */ 2511722Sjkh {'�', "...."}, /* kha */ 2521722Sjkh {'�', "-.-."}, /* ce */ 2531722Sjkh {'�', "---."}, /* che */ 2541722Sjkh {'�', "----"}, /* sha */ 25570884Sjoe {'�', "--.-"}, /* shcha */ 25629453Scharnier {'�', "-.--"}, /* yi */ 25770884Sjoe {'�', "-..-"}, /* myakhkij znak */ 25870884Sjoe {'�', "..-.."}, /* ae */ 25970884Sjoe {'�', "..--"}, /* yu */ 26070884Sjoe {'�', ".-.-"}, /* ya */ 26170884Sjoe 26270884Sjoe {'\0', ""} 2631722Sjkh}; 2641722Sjkh 2651722Sjkhvoid show(const char *), play(const char *), morse(char); 2661722Sjkhvoid ttyout(const char *); 2671722Sjkhvoid sighandler(int); 26870884Sjoe 26970884Sjoe#define GETOPTOPTS "c:d:ef:lsw:" 27070884Sjoe#define USAGE \ 27170884Sjoe"usage: morse [-els] [-d device] [-w speed] [-c speed] [-f frequency] [string ...]\n" 27270884Sjoe 2731722Sjkhstatic int pflag, lflag, sflag, eflag; 27470884Sjoestatic int wpm = 20; /* effective words per minute */ 27570884Sjoestatic int cpm; /* effective words per minute between 27670884Sjoe * characters */ 2771722Sjkh#define FREQUENCY 600 27870884Sjoestatic int freq = FREQUENCY; 27970884Sjoestatic char *device; /* for tty-controlled generator */ 28070884Sjoe 28170884Sjoe#define DASH_LEN 3 28270884Sjoe#define CHAR_SPACE 3 2831722Sjkh#define WORD_SPACE (7 - CHAR_SPACE - 1) 28470884Sjoestatic float dot_clock; 28570884Sjoestatic float cdot_clock; 28670884Sjoeint spkr, line; 28770884Sjoestruct termios otty, ntty; 28870884Sjoeint olflags; 28970884Sjoe 29070884Sjoe#ifdef SPEAKER 29170884Sjoetone_t sound; 29270884Sjoe#undef GETOPTOPTS 29370884Sjoe#define GETOPTOPTS "c:d:ef:lpsw:" 29470884Sjoe#undef USAGE 29570884Sjoe#define USAGE \ 29670884Sjoe"usage: morse [-elps] [-d device] [-w speed] [-c speed] [-f frequency] [string ...]\n" 29770884Sjoe#endif 29870884Sjoe 29970884Sjoestatic const struct morsetab *hightab; 300153687Sceri 301153687Sceriint 30270884Sjoemain(int argc, char **argv) 30370884Sjoe{ 30470884Sjoe int ch, lflags; 30570884Sjoe char *p, *codeset; 30670884Sjoe 30770884Sjoe while ((ch = getopt(argc, argv, GETOPTOPTS)) != -1) 30870884Sjoe switch ((char) ch) { 30970884Sjoe case 'c': 31070884Sjoe cpm = atoi(optarg); 31170884Sjoe break; 31270884Sjoe case 'd': 31370884Sjoe device = optarg; 31470884Sjoe break; 31570884Sjoe case 'e': 31670884Sjoe eflag = 1; 31770884Sjoe setvbuf(stdout, 0, _IONBF, 0); 31870884Sjoe break; 31970884Sjoe case 'f': 32070884Sjoe freq = atoi(optarg); 32170884Sjoe break; 3221722Sjkh case 'l': 32370884Sjoe lflag = 1; 32470884Sjoe break; 32570884Sjoe#ifdef SPEAKER 32670884Sjoe case 'p': 3271722Sjkh pflag = 1; 32870884Sjoe break; 3291722Sjkh#endif 3301722Sjkh case 's': 3311722Sjkh sflag = 1; 3321722Sjkh break; 3331722Sjkh case 'w': 33470884Sjoe wpm = atoi(optarg); 3351722Sjkh break; 33670884Sjoe case '?': 33770884Sjoe default: 3381722Sjkh fputs(USAGE, stderr); 33970884Sjoe exit(1); 34070884Sjoe } 34170884Sjoe if (sflag && lflag) { 34270884Sjoe fputs("morse: only one of -l and -s allowed\n", stderr); 34370884Sjoe exit(1); 34470884Sjoe } 34570884Sjoe if ((pflag || device) && (sflag || lflag)) { 34670884Sjoe fputs("morse: only one of -p, -d and -l, -s allowed\n", stderr); 34770884Sjoe exit(1); 34870884Sjoe } 34970884Sjoe if (cpm == 0) 35070884Sjoe cpm = wpm; 35170884Sjoe if ((pflag || device) && ((wpm < 1) || (wpm > 60) || (cpm < 1) || (cpm > 60))) { 35270884Sjoe fputs("morse: insane speed\n", stderr); 35370884Sjoe exit(1); 35470884Sjoe } 35570884Sjoe if ((pflag || device) && (freq == 0)) 35670884Sjoe freq = FREQUENCY; 35770884Sjoe 35870884Sjoe#ifdef SPEAKER 35970884Sjoe if (pflag) { 3601722Sjkh if ((spkr = open(SPEAKER, O_WRONLY, 0)) == -1) { 3611722Sjkh perror(SPEAKER); 3621722Sjkh exit(1); 3631722Sjkh } 3641722Sjkh } else 36570884Sjoe#endif 3661722Sjkh if (device) { 36770884Sjoe if ((line = open(device, O_WRONLY | O_NONBLOCK)) == -1) { 36870884Sjoe perror("open tty line"); 36970884Sjoe exit(1); 37070884Sjoe } 37170884Sjoe if (tcgetattr(line, &otty) == -1) { 37270884Sjoe perror("tcgetattr() failed"); 37370884Sjoe exit(1); 37470884Sjoe } 3751722Sjkh ntty = otty; 3761722Sjkh ntty.c_cflag |= CLOCAL; 3771722Sjkh tcsetattr(line, TCSANOW, &ntty); 3781722Sjkh lflags = fcntl(line, F_GETFL); 3791722Sjkh lflags &= ~O_NONBLOCK; 3801722Sjkh fcntl(line, F_SETFL, &lflags); 38170884Sjoe ioctl(line, TIOCMGET, &lflags); 3821722Sjkh lflags &= ~TIOCM_RTS; 38370884Sjoe olflags = lflags; 38470884Sjoe ioctl(line, TIOCMSET, &lflags); 3851722Sjkh (void)signal(SIGHUP, sighandler); 3861722Sjkh (void)signal(SIGINT, sighandler); 3871722Sjkh (void)signal(SIGQUIT, sighandler); 3881722Sjkh (void)signal(SIGTERM, sighandler); 3891722Sjkh } 39070884Sjoe if (pflag || device) { 3911722Sjkh dot_clock = wpm / 2.4; /* dots/sec */ 39270884Sjoe dot_clock = 1 / dot_clock; /* duration of a dot */ 3931722Sjkh dot_clock = dot_clock / 2; /* dot_clock runs at twice */ 39470884Sjoe /* the dot rate */ 39570884Sjoe dot_clock = dot_clock * 100; /* scale for ioctl */ 39670884Sjoe 3971722Sjkh cdot_clock = cpm / 2.4; /* dots/sec */ 39870884Sjoe cdot_clock = 1 / cdot_clock; /* duration of a dot */ 39970884Sjoe cdot_clock = cdot_clock / 2; /* dot_clock runs at twice */ 40070884Sjoe /* the dot rate */ 40170884Sjoe cdot_clock = cdot_clock * 100; /* scale for ioctl */ 40270884Sjoe } 40370884Sjoe 40470884Sjoe argc -= optind; 4051722Sjkh argv += optind; 40670884Sjoe 40770884Sjoe if (setlocale(LC_CTYPE, "") != NULL && 40870884Sjoe *(codeset = nl_langinfo(CODESET)) != '\0') { 40970884Sjoe if (strcmp(codeset, "KOI8-R") == 0) 41070884Sjoe hightab = koi8rtab; 4111722Sjkh else if (strcmp(codeset, "ISO8859-1") == 0 || 41270884Sjoe strcmp(codeset, "ISO8859-15") == 0) 41370884Sjoe hightab = iso8859_1tab; 41470884Sjoe else if (strcmp(codeset, "ISO8859-7") == 0) 41570884Sjoe hightab = iso8859_7tab; 41670884Sjoe } 41793435Sluigi 418153687Sceri if (lflag) 41970884Sjoe printf("m"); 42070884Sjoe if (*argv) { 42170884Sjoe do { 42270884Sjoe for (p = *argv; *p; ++p) { 42370884Sjoe if (eflag) 42470884Sjoe putchar(*p); 42570884Sjoe morse(*p); 4261722Sjkh } 4271722Sjkh if (eflag) 4281722Sjkh putchar(' '); 4291722Sjkh morse(' '); 4301722Sjkh } while (*++argv); 43170884Sjoe } else { 43270884Sjoe while ((ch = getchar()) != EOF) { 4331722Sjkh if (eflag) 43470884Sjoe putchar(ch); 43570884Sjoe morse(ch); 43670884Sjoe } 43770884Sjoe } 43870884Sjoe if (device) 43970884Sjoe tcsetattr(line, TCSANOW, &otty); 44070884Sjoe exit(0); 44170884Sjoe} 44270884Sjoe 44370884Sjoevoid 44470884Sjoemorse(char c) 44570884Sjoe{ 44670884Sjoe const struct morsetab *m; 4471722Sjkh 4481722Sjkh if (isalpha((unsigned char)c)) 4491722Sjkh c = tolower((unsigned char)c); 4501722Sjkh if ((c == '\r') || (c == '\n')) 4511722Sjkh c = ' '; 45270884Sjoe if (c == ' ') { 4531722Sjkh if (pflag) 454153687Sceri play(" "); 45570884Sjoe else if (device) 456153687Sceri ttyout(" "); 457153687Sceri else if (lflag) 458153687Sceri printf("\n"); 459153687Sceri else 460153687Sceri show(""); 4611722Sjkh return; 4621722Sjkh } 4631722Sjkh for (m = ((unsigned char)c < 0x80? mtab: hightab); 464153687Sceri m != NULL && m->inchar != '\0'; 465153687Sceri m++) { 466153687Sceri if (m->inchar == c) { 467153687Sceri if (pflag) { 468153687Sceri play(m->morse); 469153687Sceri } else if (device) { 470153687Sceri ttyout(m->morse); 471153687Sceri } else 472153687Sceri show(m->morse); 473153687Sceri } 474153687Sceri } 475153687Sceri} 476153687Sceri 477153687Scerivoid 47868750Sjoeshow(const char *s) 47968750Sjoe{ 48070884Sjoe if (lflag) { 48168750Sjoe printf("%s ", s); 48270884Sjoe } else if (sflag) { 48370884Sjoe printf(" %s\n", s); 48468750Sjoe } else { 48568750Sjoe for (; *s; ++s) 48668750Sjoe printf(" %s", *s == '.' ? "dit" : "dah"); 4871722Sjkh printf("\n"); 4881722Sjkh } 48970884Sjoe} 49070884Sjoe 4911722Sjkhvoid 49270884Sjoeplay(const char *s) 49370884Sjoe{ 49470884Sjoe#ifdef SPEAKER 4951722Sjkh const char *c; 49670884Sjoe 49770884Sjoe for (c = s; *c != '\0'; c++) { 49870884Sjoe switch (*c) { 49970884Sjoe case '.': 50070884Sjoe sound.frequency = freq; 5011722Sjkh sound.duration = dot_clock; 50270884Sjoe break; 50370884Sjoe case '-': 50470884Sjoe sound.frequency = freq; 50570884Sjoe sound.duration = dot_clock * DASH_LEN; 50670884Sjoe break; 50770884Sjoe case ' ': 50870884Sjoe sound.frequency = 0; 50970884Sjoe sound.duration = cdot_clock * WORD_SPACE; 51070884Sjoe break; 51170884Sjoe default: 51270884Sjoe sound.duration = 0; 51370884Sjoe } 51470884Sjoe if (sound.duration) { 51570884Sjoe if (ioctl(spkr, SPKRTONE, &sound) == -1) { 51670884Sjoe perror("ioctl play"); 51770884Sjoe exit(1); 51870884Sjoe } 51970884Sjoe } 52070884Sjoe sound.frequency = 0; 52170884Sjoe sound.duration = dot_clock; 52270884Sjoe if (ioctl(spkr, SPKRTONE, &sound) == -1) { 52370884Sjoe perror("ioctl rest"); 52470884Sjoe exit(1); 52570884Sjoe } 52670884Sjoe } 52770884Sjoe sound.frequency = 0; 52870884Sjoe sound.duration = cdot_clock * CHAR_SPACE; 52970884Sjoe ioctl(spkr, SPKRTONE, &sound); 53070884Sjoe#endif 53170884Sjoe} 53270884Sjoe 53370884Sjoevoid 53470884Sjoettyout(const char *s) 53570884Sjoe{ 53670884Sjoe const char *c; 53770884Sjoe int duration, on, lflags; 53893435Sluigi 53993435Sluigi for (c = s; *c != '\0'; c++) { 54093435Sluigi switch (*c) { 54170884Sjoe case '.': 54270884Sjoe on = 1; 54370884Sjoe duration = dot_clock; 54470884Sjoe break; 54570884Sjoe case '-': 54670884Sjoe on = 1; 5471722Sjkh duration = dot_clock * DASH_LEN; 5481722Sjkh break; 54970884Sjoe case ' ': 5501722Sjkh on = 0; 55170884Sjoe duration = cdot_clock * WORD_SPACE; 5521722Sjkh break; 5531722Sjkh default: 5541722Sjkh on = 0; 5551722Sjkh duration = 0; 5561722Sjkh } 55770884Sjoe if (on) { 5581722Sjkh ioctl(line, TIOCMGET, &lflags); 55970884Sjoe lflags |= TIOCM_RTS; 56070884Sjoe ioctl(line, TIOCMSET, &lflags); 56170884Sjoe } 5621722Sjkh duration *= 10000; 56370884Sjoe if (duration) 5641722Sjkh usleep(duration); 5651722Sjkh ioctl(line, TIOCMGET, &lflags); 5661722Sjkh lflags &= ~TIOCM_RTS; 5671722Sjkh ioctl(line, TIOCMSET, &lflags); 5681722Sjkh duration = dot_clock * 10000; 5691722Sjkh usleep(duration); 5701722Sjkh } 5711722Sjkh duration = cdot_clock * CHAR_SPACE * 10000; 5721722Sjkh usleep(duration); 5731722Sjkh} 5741722Sjkh 5751722Sjkhvoid 5761722Sjkhsighandler(int signo) 5771722Sjkh{ 5781722Sjkh 5791722Sjkh ioctl(line, TIOCMSET, &olflags); 5801722Sjkh tcsetattr(line, TCSANOW, &otty); 5811722Sjkh 5821722Sjkh signal(signo, SIG_DFL); 5831722Sjkh (void)kill(getpid(), signo); 5841722Sjkh} 5851722Sjkh