morse.c revision 203932
12490Sjkh/* 22490Sjkh * Copyright (c) 1988, 1993 32490Sjkh * The Regents of the University of California. All rights reserved. 42490Sjkh * 52490Sjkh * Redistribution and use in source and binary forms, with or without 62490Sjkh * modification, are permitted provided that the following conditions 72490Sjkh * are met: 82490Sjkh * 1. Redistributions of source code must retain the above copyright 92490Sjkh * notice, this list of conditions and the following disclaimer. 102490Sjkh * 2. Redistributions in binary form must reproduce the above copyright 112490Sjkh * notice, this list of conditions and the following disclaimer in the 122490Sjkh * documentation and/or other materials provided with the distribution. 13203932Simp * 3. Neither the name of the University nor the names of its contributors 142490Sjkh * may be used to endorse or promote products derived from this software 152490Sjkh * without specific prior written permission. 162490Sjkh * 172490Sjkh * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 182490Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 192490Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 202490Sjkh * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 212490Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 222490Sjkh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 232490Sjkh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 242490Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 252490Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 262490Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 272490Sjkh * SUCH DAMAGE. 282490Sjkh */ 292490Sjkh 3010352Sjoerg/* 31179654Sscf * Taught to send *real* morse by Lyndon Nerenberg (VE6BBM) 32179654Sscf * <lyndon@orthanc.ca> 3310352Sjoerg */ 3410352Sjoerg 352490Sjkh#ifndef lint 3653920Sbillfstatic const char copyright[] = 372490Sjkh"@(#) Copyright (c) 1988, 1993\n\ 382490Sjkh The Regents of the University of California. All rights reserved.\n"; 392490Sjkh#endif /* not lint */ 402490Sjkh 412490Sjkh#ifndef lint 4253920Sbillf#if 0 432490Sjkhstatic char sccsid[] = "@(#)morse.c 8.1 (Berkeley) 5/31/93"; 4453920Sbillf#endif 4553920Sbillfstatic const char rcsid[] = 4653920Sbillf "$FreeBSD: head/games/morse/morse.c 203932 2010-02-15 18:46:02Z imp $"; 472490Sjkh#endif /* not lint */ 482490Sjkh 4957527Sjoerg#include <sys/time.h> 5057527Sjoerg 512490Sjkh#include <ctype.h> 5257527Sjoerg#include <fcntl.h> 5378793Sache#include <langinfo.h> 5410352Sjoerg#include <locale.h> 5557527Sjoerg#include <signal.h> 5657527Sjoerg#include <stdio.h> 5710352Sjoerg#include <stdlib.h> 5835857Sjb#include <string.h> 5957527Sjoerg#include <termios.h> 6054622Sbillf#include <unistd.h> 612490Sjkh 62203479Simp/* Always use the speaker, let the open fail if -p is selected */ 63203479Simp#define SPEAKER "/dev/speaker" 64203479Simp 6510352Sjoerg#ifdef SPEAKER 66152306Sru#include <dev/speaker/speaker.h> 6710352Sjoerg#endif 6810352Sjoerg 6910352Sjoergstruct morsetab { 70203921Suqs const char inchar; 71203921Suqs const char *morse; 722490Sjkh}; 732490Sjkh 7454622Sbillfstatic const struct morsetab mtab[] = { 752490Sjkh 7610352Sjoerg /* letters */ 7710352Sjoerg 7854622Sbillf {'a', ".-"}, 7954622Sbillf {'b', "-..."}, 8054622Sbillf {'c', "-.-."}, 8154622Sbillf {'d', "-.."}, 8254622Sbillf {'e', "."}, 8354622Sbillf {'f', "..-."}, 8454622Sbillf {'g', "--."}, 8554622Sbillf {'h', "...."}, 8654622Sbillf {'i', ".."}, 8754622Sbillf {'j', ".---"}, 8854622Sbillf {'k', "-.-"}, 8954622Sbillf {'l', ".-.."}, 9054622Sbillf {'m', "--"}, 9154622Sbillf {'n', "-."}, 9254622Sbillf {'o', "---"}, 9354622Sbillf {'p', ".--."}, 9454622Sbillf {'q', "--.-"}, 9554622Sbillf {'r', ".-."}, 9654622Sbillf {'s', "..."}, 9754622Sbillf {'t', "-"}, 9854622Sbillf {'u', "..-"}, 9954622Sbillf {'v', "...-"}, 10054622Sbillf {'w', ".--"}, 10154622Sbillf {'x', "-..-"}, 10254622Sbillf {'y', "-.--"}, 10354622Sbillf {'z', "--.."}, 10410352Sjoerg 10510352Sjoerg /* digits */ 10610352Sjoerg 10754622Sbillf {'0', "-----"}, 10854622Sbillf {'1', ".----"}, 10954622Sbillf {'2', "..---"}, 11054622Sbillf {'3', "...--"}, 11154622Sbillf {'4', "....-"}, 11254622Sbillf {'5', "....."}, 11354622Sbillf {'6', "-...."}, 11454622Sbillf {'7', "--..."}, 11554622Sbillf {'8', "---.."}, 11654622Sbillf {'9', "----."}, 11710352Sjoerg 11810352Sjoerg /* punctuation */ 11910352Sjoerg 12054622Sbillf {',', "--..--"}, 12154622Sbillf {'.', ".-.-.-"}, 122126040Sfanf {'"', ".-..-."}, 123126040Sfanf {'!', "..--."}, 12454622Sbillf {'?', "..--.."}, 12554622Sbillf {'/', "-..-."}, 12654622Sbillf {'-', "-....-"}, 12754622Sbillf {'=', "-...-"}, /* BT */ 12854622Sbillf {':', "---..."}, 12954622Sbillf {';', "-.-.-."}, 13054622Sbillf {'(', "-.--."}, /* KN */ 13154622Sbillf {')', "-.--.-"}, 13254622Sbillf {'$', "...-..-"}, 13354622Sbillf {'+', ".-.-."}, /* AR */ 134126044Sfanf {'@', ".--.-."}, /* AC */ 13510352Sjoerg 13610352Sjoerg /* prosigns without already assigned values */ 13710352Sjoerg 13854622Sbillf {'#', ".-..."}, /* AS */ 139126040Sfanf {'&', "...-.-"}, /* SK */ 14054622Sbillf {'*', "...-."}, /* VE */ 14154622Sbillf {'%', "-...-.-"}, /* BK */ 14210352Sjoerg 14354622Sbillf {'\0', ""} 14410352Sjoerg}; 14510352Sjoerg 14610352Sjoerg 147129114Sddsstatic const struct morsetab iso8859_1tab[] = { 14854622Sbillf {'�', ".--.-"}, 14954622Sbillf {'�', ".--.-"}, 15054622Sbillf {'�', ".--.-"}, 15154622Sbillf {'�', ".-.-"}, 15254622Sbillf {'�', "-.-.."}, 15354622Sbillf {'�', "..-.."}, 15454622Sbillf {'�', "..-.."}, 15554622Sbillf {'�', "-..-."}, 15654622Sbillf {'�', "---."}, 15754622Sbillf {'�', "..--"}, 15810352Sjoerg 15954622Sbillf {'\0', ""} 16010352Sjoerg}; 16110352Sjoerg 162129114Sddsstatic const struct morsetab iso8859_7tab[] = { 163129114Sdds /* 164129114Sdds * The greek alphabet; you'll need an 8859-7 font in order 165129114Sdds * to see the actual characters. 166129114Sdds * This table does not implement: 167129114Sdds * - the special sequences for the seven diphthongs, 168129114Sdds * - the punctuation differences. 169129114Sdds * Implementing these features would introduce too many 170129114Sdds * special-cases in the program's main loop. 171129114Sdds * The diphtong sequences are: 172129114Sdds * alpha iota .-.- 173129114Sdds * alpha upsilon ..-- 174129114Sdds * epsilon upsilon ---. 175129114Sdds * eta upsilon ...- 176129114Sdds * omikron iota ---.. 177129114Sdds * omikron upsilon ..- 178129114Sdds * upsilon iota .--- 179129114Sdds * The different punctuation symbols are: 180129114Sdds * ; ..-.- 181129114Sdds * ! --..-- 182129114Sdds */ 183129114Sdds {'�', ".-"}, /* alpha */ 184129114Sdds {'�', ".-"}, /* alpha with acute */ 185129114Sdds {'�', "-..."}, /* beta */ 186129114Sdds {'�', "--."}, /* gamma */ 187129114Sdds {'�', "-.."}, /* delta */ 188129114Sdds {'�', "."}, /* epsilon */ 189129114Sdds {'�', "."}, /* epsilon with acute */ 190129114Sdds {'�', "--.."}, /* zeta */ 191129114Sdds {'�', "...."}, /* eta */ 192129114Sdds {'�', "...."}, /* eta with acute */ 193129114Sdds {'�', "-.-."}, /* theta */ 194129114Sdds {'�', ".."}, /* iota */ 195129114Sdds {'�', ".."}, /* iota with acute */ 196129114Sdds {'�', ".."}, /* iota with diairesis */ 197129114Sdds {'�', ".."}, /* iota with acute and diairesis */ 198129114Sdds {'�', "-.-"}, /* kappa */ 199129114Sdds {'�', ".-.."}, /* lamda */ 200129114Sdds {'�', "--"}, /* mu */ 201129114Sdds {'�', "-."}, /* nu */ 202129114Sdds {'�', "-..-"}, /* xi */ 203129114Sdds {'�', "---"}, /* omicron */ 204129114Sdds {'�', "---"}, /* omicron with acute */ 205129114Sdds {'�', ".--."}, /* pi */ 206129114Sdds {'�', ".-."}, /* rho */ 207129114Sdds {'�', "..."}, /* sigma */ 208129114Sdds {'�', "..."}, /* final sigma */ 209129114Sdds {'�', "-"}, /* tau */ 210129114Sdds {'�', "-.--"}, /* upsilon */ 211129114Sdds {'�', "-.--"}, /* upsilon with acute */ 212129114Sdds {'�', "-.--"}, /* upsilon and diairesis */ 213129114Sdds {'�', "-.--"}, /* upsilon with acute and diairesis */ 214129114Sdds {'�', "..-."}, /* phi */ 215129114Sdds {'�', "----"}, /* chi */ 216129114Sdds {'�', "--.-"}, /* psi */ 217129114Sdds {'�', ".--"}, /* omega */ 218129114Sdds {'�', ".--"}, /* omega with acute */ 219129114Sdds 220129114Sdds {'\0', ""} 221129114Sdds}; 222129114Sdds 22354622Sbillfstatic const struct morsetab koi8rtab[] = { 22410352Sjoerg /* 22510352Sjoerg * the cyrillic alphabet; you'll need a KOI8R font in order 22610352Sjoerg * to see the actual characters 22710352Sjoerg */ 22854622Sbillf {'�', ".-"}, /* a */ 22954622Sbillf {'�', "-..."}, /* be */ 23054622Sbillf {'�', ".--"}, /* ve */ 23154622Sbillf {'�', "--."}, /* ge */ 23254622Sbillf {'�', "-.."}, /* de */ 23354622Sbillf {'�', "."}, /* ye */ 23454622Sbillf {'�', "."}, /* yo, the same as ye */ 23554622Sbillf {'�', "...-"}, /* she */ 23654622Sbillf {'�', "--.."}, /* ze */ 23754622Sbillf {'�', ".."}, /* i */ 23854622Sbillf {'�', ".---"}, /* i kratkoye */ 23954622Sbillf {'�', "-.-"}, /* ka */ 24054622Sbillf {'�', ".-.."}, /* el */ 24154622Sbillf {'�', "--"}, /* em */ 24254622Sbillf {'�', "-."}, /* en */ 24354622Sbillf {'�', "---"}, /* o */ 24454622Sbillf {'�', ".--."}, /* pe */ 24554622Sbillf {'�', ".-."}, /* er */ 24654622Sbillf {'�', "..."}, /* es */ 24754622Sbillf {'�', "-"}, /* te */ 24854622Sbillf {'�', "..-"}, /* u */ 24954622Sbillf {'�', "..-."}, /* ef */ 25054622Sbillf {'�', "...."}, /* kha */ 25154622Sbillf {'�', "-.-."}, /* ce */ 25254622Sbillf {'�', "---."}, /* che */ 25354622Sbillf {'�', "----"}, /* sha */ 25454622Sbillf {'�', "--.-"}, /* shcha */ 25554622Sbillf {'�', "-.--"}, /* yi */ 25654622Sbillf {'�', "-..-"}, /* myakhkij znak */ 25754622Sbillf {'�', "..-.."}, /* ae */ 25854622Sbillf {'�', "..--"}, /* yu */ 25954622Sbillf {'�', ".-.-"}, /* ya */ 26010352Sjoerg 26154622Sbillf {'\0', ""} 26210352Sjoerg}; 26310352Sjoerg 26410352Sjoergvoid show(const char *), play(const char *), morse(char); 26557527Sjoergvoid ttyout(const char *); 26657527Sjoergvoid sighandler(int); 26710352Sjoerg 268147110Sjoerg#define GETOPTOPTS "c:d:ef:lsw:" 26957527Sjoerg#define USAGE \ 270147110Sjoerg"usage: morse [-els] [-d device] [-w speed] [-c speed] [-f frequency] [string ...]\n" 27157527Sjoerg 272121945Sphkstatic int pflag, lflag, sflag, eflag; 273147110Sjoergstatic int wpm = 20; /* effective words per minute */ 274147110Sjoergstatic int cpm; /* effective words per minute between 275147110Sjoerg * characters */ 27610352Sjoerg#define FREQUENCY 600 27710352Sjoergstatic int freq = FREQUENCY; 27857527Sjoergstatic char *device; /* for tty-controlled generator */ 27910352Sjoerg 28010352Sjoerg#define DASH_LEN 3 28110352Sjoerg#define CHAR_SPACE 3 28210352Sjoerg#define WORD_SPACE (7 - CHAR_SPACE - 1) 28310352Sjoergstatic float dot_clock; 284147110Sjoergstatic float cdot_clock; 28557527Sjoergint spkr, line; 28657527Sjoergstruct termios otty, ntty; 28757527Sjoergint olflags; 28857527Sjoerg 28957527Sjoerg#ifdef SPEAKER 29010352Sjoergtone_t sound; 29157527Sjoerg#undef GETOPTOPTS 292147110Sjoerg#define GETOPTOPTS "c:d:ef:lpsw:" 29357527Sjoerg#undef USAGE 29457527Sjoerg#define USAGE \ 295147110Sjoerg"usage: morse [-elps] [-d device] [-w speed] [-c speed] [-f frequency] [string ...]\n" 29610352Sjoerg#endif 29710352Sjoerg 29878793Sachestatic const struct morsetab *hightab; 29910352Sjoerg 30010352Sjoergint 30110352Sjoergmain(int argc, char **argv) 3022490Sjkh{ 30357527Sjoerg int ch, lflags; 30478793Sache char *p, *codeset; 3052490Sjkh 30657527Sjoerg while ((ch = getopt(argc, argv, GETOPTOPTS)) != -1) 30710352Sjoerg switch ((char) ch) { 308147110Sjoerg case 'c': 309147110Sjoerg cpm = atoi(optarg); 310147110Sjoerg break; 31157527Sjoerg case 'd': 31257527Sjoerg device = optarg; 31357527Sjoerg break; 31457527Sjoerg case 'e': 31557527Sjoerg eflag = 1; 31657527Sjoerg setvbuf(stdout, 0, _IONBF, 0); 31757527Sjoerg break; 31810352Sjoerg case 'f': 31910352Sjoerg freq = atoi(optarg); 32010352Sjoerg break; 321121945Sphk case 'l': 322121945Sphk lflag = 1; 323121945Sphk break; 32457527Sjoerg#ifdef SPEAKER 32510352Sjoerg case 'p': 32610352Sjoerg pflag = 1; 32710352Sjoerg break; 32857527Sjoerg#endif 3292490Sjkh case 's': 3302490Sjkh sflag = 1; 3312490Sjkh break; 33210352Sjoerg case 'w': 33310352Sjoerg wpm = atoi(optarg); 33410352Sjoerg break; 3352490Sjkh case '?': 3362490Sjkh default: 33757527Sjoerg fputs(USAGE, stderr); 3382490Sjkh exit(1); 3392490Sjkh } 340121945Sphk if (sflag && lflag) { 341121945Sphk fputs("morse: only one of -l and -s allowed\n", stderr); 34210352Sjoerg exit(1); 34310352Sjoerg } 344121945Sphk if ((pflag || device) && (sflag || lflag)) { 345121945Sphk fputs("morse: only one of -p, -d and -l, -s allowed\n", stderr); 346121945Sphk exit(1); 347121945Sphk } 348147110Sjoerg if (cpm == 0) 349147110Sjoerg cpm = wpm; 350147110Sjoerg if ((pflag || device) && ((wpm < 1) || (wpm > 60) || (cpm < 1) || (cpm > 60))) { 35110352Sjoerg fputs("morse: insane speed\n", stderr); 35210352Sjoerg exit(1); 35310352Sjoerg } 35457527Sjoerg if ((pflag || device) && (freq == 0)) 35510352Sjoerg freq = FREQUENCY; 35610352Sjoerg 35710352Sjoerg#ifdef SPEAKER 35810352Sjoerg if (pflag) { 35910352Sjoerg if ((spkr = open(SPEAKER, O_WRONLY, 0)) == -1) { 36010352Sjoerg perror(SPEAKER); 36110352Sjoerg exit(1); 36210352Sjoerg } 36357527Sjoerg } else 36457527Sjoerg#endif 36557527Sjoerg if (device) { 36657527Sjoerg if ((line = open(device, O_WRONLY | O_NONBLOCK)) == -1) { 36757527Sjoerg perror("open tty line"); 36857527Sjoerg exit(1); 36957527Sjoerg } 37057527Sjoerg if (tcgetattr(line, &otty) == -1) { 37157527Sjoerg perror("tcgetattr() failed"); 37257527Sjoerg exit(1); 37357527Sjoerg } 37457527Sjoerg ntty = otty; 37557527Sjoerg ntty.c_cflag |= CLOCAL; 37657527Sjoerg tcsetattr(line, TCSANOW, &ntty); 37757527Sjoerg lflags = fcntl(line, F_GETFL); 37857527Sjoerg lflags &= ~O_NONBLOCK; 37957527Sjoerg fcntl(line, F_SETFL, &lflags); 38057527Sjoerg ioctl(line, TIOCMGET, &lflags); 38157527Sjoerg lflags &= ~TIOCM_RTS; 38257527Sjoerg olflags = lflags; 38357527Sjoerg ioctl(line, TIOCMSET, &lflags); 38457527Sjoerg (void)signal(SIGHUP, sighandler); 38557527Sjoerg (void)signal(SIGINT, sighandler); 38657527Sjoerg (void)signal(SIGQUIT, sighandler); 38757527Sjoerg (void)signal(SIGTERM, sighandler); 38857527Sjoerg } 38957527Sjoerg if (pflag || device) { 39010352Sjoerg dot_clock = wpm / 2.4; /* dots/sec */ 39110352Sjoerg dot_clock = 1 / dot_clock; /* duration of a dot */ 39210352Sjoerg dot_clock = dot_clock / 2; /* dot_clock runs at twice */ 39310352Sjoerg /* the dot rate */ 39410352Sjoerg dot_clock = dot_clock * 100; /* scale for ioctl */ 395147110Sjoerg 396147110Sjoerg cdot_clock = cpm / 2.4; /* dots/sec */ 397147110Sjoerg cdot_clock = 1 / cdot_clock; /* duration of a dot */ 398147110Sjoerg cdot_clock = cdot_clock / 2; /* dot_clock runs at twice */ 399147110Sjoerg /* the dot rate */ 400147110Sjoerg cdot_clock = cdot_clock * 100; /* scale for ioctl */ 40110352Sjoerg } 40257527Sjoerg 4032490Sjkh argc -= optind; 4042490Sjkh argv += optind; 4052490Sjkh 40678793Sache if (setlocale(LC_CTYPE, "") != NULL && 40778793Sache *(codeset = nl_langinfo(CODESET)) != '\0') { 40878793Sache if (strcmp(codeset, "KOI8-R") == 0) 40910352Sjoerg hightab = koi8rtab; 41078793Sache else if (strcmp(codeset, "ISO8859-1") == 0 || 41178793Sache strcmp(codeset, "ISO8859-15") == 0) 412129114Sdds hightab = iso8859_1tab; 413129114Sdds else if (strcmp(codeset, "ISO8859-7") == 0) 414129114Sdds hightab = iso8859_7tab; 41510352Sjoerg } 41610352Sjoerg 417121945Sphk if (lflag) 418121945Sphk printf("m"); 41910352Sjoerg if (*argv) { 4202490Sjkh do { 42110352Sjoerg for (p = *argv; *p; ++p) { 42257527Sjoerg if (eflag) 42357527Sjoerg putchar(*p); 42429018Sache morse(*p); 42510352Sjoerg } 42657527Sjoerg if (eflag) 42757527Sjoerg putchar(' '); 42829018Sache morse(' '); 4292490Sjkh } while (*++argv); 43010352Sjoerg } else { 43157527Sjoerg while ((ch = getchar()) != EOF) { 43257527Sjoerg if (eflag) 43357527Sjoerg putchar(ch); 43410352Sjoerg morse(ch); 43557527Sjoerg } 43610352Sjoerg } 43757527Sjoerg if (device) 43857527Sjoerg tcsetattr(line, TCSANOW, &otty); 43910352Sjoerg exit(0); 4402490Sjkh} 4412490Sjkh 44210352Sjoergvoid 44310352Sjoergmorse(char c) 4442490Sjkh{ 44554622Sbillf const struct morsetab *m; 44610352Sjoerg 44729018Sache if (isalpha((unsigned char)c)) 44829018Sache c = tolower((unsigned char)c); 44910352Sjoerg if ((c == '\r') || (c == '\n')) 45010352Sjoerg c = ' '; 45110352Sjoerg if (c == ' ') { 452121945Sphk if (pflag) 45310352Sjoerg play(" "); 454121945Sphk else if (device) 45557527Sjoerg ttyout(" "); 456121945Sphk else if (lflag) 457121945Sphk printf("\n"); 458121945Sphk else 45910352Sjoerg show(""); 460121945Sphk return; 46110352Sjoerg } 46210352Sjoerg for (m = ((unsigned char)c < 0x80? mtab: hightab); 46378793Sache m != NULL && m->inchar != '\0'; 46410352Sjoerg m++) { 46510352Sjoerg if (m->inchar == c) { 46610352Sjoerg if (pflag) { 46710352Sjoerg play(m->morse); 46857527Sjoerg } else if (device) { 46957527Sjoerg ttyout(m->morse); 47010352Sjoerg } else 47110352Sjoerg show(m->morse); 47210352Sjoerg } 47310352Sjoerg } 4742490Sjkh} 4752490Sjkh 47610352Sjoergvoid 47710352Sjoergshow(const char *s) 4782490Sjkh{ 479121945Sphk if (lflag) { 480121945Sphk printf("%s ", s); 481121945Sphk } else if (sflag) { 482121945Sphk printf(" %s\n", s); 483121945Sphk } else { 48410352Sjoerg for (; *s; ++s) 485179654Sscf printf(" %s", *s == '.' ? *(s + 1) == '\0' ? "dit" : 486179654Sscf "di" : "dah"); 487121945Sphk printf("\n"); 488121945Sphk } 4892490Sjkh} 49010352Sjoerg 49110352Sjoergvoid 49210352Sjoergplay(const char *s) 49310352Sjoerg{ 49410352Sjoerg#ifdef SPEAKER 49510352Sjoerg const char *c; 49610352Sjoerg 49710352Sjoerg for (c = s; *c != '\0'; c++) { 49829018Sache switch (*c) { 49910352Sjoerg case '.': 50010352Sjoerg sound.frequency = freq; 50110352Sjoerg sound.duration = dot_clock; 50210352Sjoerg break; 50310352Sjoerg case '-': 50410352Sjoerg sound.frequency = freq; 50510352Sjoerg sound.duration = dot_clock * DASH_LEN; 50610352Sjoerg break; 50710352Sjoerg case ' ': 50810352Sjoerg sound.frequency = 0; 509147110Sjoerg sound.duration = cdot_clock * WORD_SPACE; 51010352Sjoerg break; 51110352Sjoerg default: 51210352Sjoerg sound.duration = 0; 51310352Sjoerg } 51410352Sjoerg if (sound.duration) { 51510352Sjoerg if (ioctl(spkr, SPKRTONE, &sound) == -1) { 51610352Sjoerg perror("ioctl play"); 51710352Sjoerg exit(1); 51810352Sjoerg } 51910352Sjoerg } 52010352Sjoerg sound.frequency = 0; 52110352Sjoerg sound.duration = dot_clock; 52210352Sjoerg if (ioctl(spkr, SPKRTONE, &sound) == -1) { 52310352Sjoerg perror("ioctl rest"); 52410352Sjoerg exit(1); 52510352Sjoerg } 52610352Sjoerg } 52710352Sjoerg sound.frequency = 0; 528147110Sjoerg sound.duration = cdot_clock * CHAR_SPACE; 52910352Sjoerg ioctl(spkr, SPKRTONE, &sound); 53010352Sjoerg#endif 53110352Sjoerg} 53257527Sjoerg 53357527Sjoergvoid 53457527Sjoergttyout(const char *s) 53557527Sjoerg{ 53657527Sjoerg const char *c; 53757527Sjoerg int duration, on, lflags; 53857527Sjoerg 53957527Sjoerg for (c = s; *c != '\0'; c++) { 54057527Sjoerg switch (*c) { 54157527Sjoerg case '.': 54257527Sjoerg on = 1; 54357527Sjoerg duration = dot_clock; 54457527Sjoerg break; 54557527Sjoerg case '-': 54657527Sjoerg on = 1; 54757527Sjoerg duration = dot_clock * DASH_LEN; 54857527Sjoerg break; 54957527Sjoerg case ' ': 55057527Sjoerg on = 0; 551147110Sjoerg duration = cdot_clock * WORD_SPACE; 55257527Sjoerg break; 55357527Sjoerg default: 55457527Sjoerg on = 0; 55557527Sjoerg duration = 0; 55657527Sjoerg } 55757527Sjoerg if (on) { 55857527Sjoerg ioctl(line, TIOCMGET, &lflags); 55957527Sjoerg lflags |= TIOCM_RTS; 56057527Sjoerg ioctl(line, TIOCMSET, &lflags); 56157527Sjoerg } 56257527Sjoerg duration *= 10000; 56357527Sjoerg if (duration) 56457527Sjoerg usleep(duration); 56557527Sjoerg ioctl(line, TIOCMGET, &lflags); 56657527Sjoerg lflags &= ~TIOCM_RTS; 56757527Sjoerg ioctl(line, TIOCMSET, &lflags); 56857527Sjoerg duration = dot_clock * 10000; 56957527Sjoerg usleep(duration); 57057527Sjoerg } 571147110Sjoerg duration = cdot_clock * CHAR_SPACE * 10000; 57257527Sjoerg usleep(duration); 57357527Sjoerg} 57457527Sjoerg 57557527Sjoergvoid 57657527Sjoergsighandler(int signo) 57757527Sjoerg{ 57857527Sjoerg 57957527Sjoerg ioctl(line, TIOCMSET, &olflags); 58057527Sjoerg tcsetattr(line, TCSANOW, &otty); 58157527Sjoerg 58257527Sjoerg signal(signo, SIG_DFL); 58357527Sjoerg (void)kill(getpid(), signo); 58457527Sjoerg} 585