morse.c revision 147110
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. 132490Sjkh * 3. All advertising materials mentioning features or use of this software 142490Sjkh * must display the following acknowledgement: 152490Sjkh * This product includes software developed by the University of 162490Sjkh * California, Berkeley and its contributors. 172490Sjkh * 4. Neither the name of the University nor the names of its contributors 182490Sjkh * may be used to endorse or promote products derived from this software 192490Sjkh * without specific prior written permission. 202490Sjkh * 212490Sjkh * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 222490Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 232490Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 242490Sjkh * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 252490Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 262490Sjkh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 272490Sjkh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 282490Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 292490Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 302490Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 312490Sjkh * SUCH DAMAGE. 322490Sjkh */ 332490Sjkh 3410352Sjoerg/* 3510352Sjoerg * Taught to send *real* morse by Lyndon Nerenberg (VE7TCP/VE6BBM) 3610352Sjoerg * <lyndon@orthanc.com> 3710352Sjoerg */ 3810352Sjoerg 392490Sjkh#ifndef lint 4053920Sbillfstatic const char copyright[] = 412490Sjkh"@(#) Copyright (c) 1988, 1993\n\ 422490Sjkh The Regents of the University of California. All rights reserved.\n"; 432490Sjkh#endif /* not lint */ 442490Sjkh 452490Sjkh#ifndef lint 4653920Sbillf#if 0 472490Sjkhstatic char sccsid[] = "@(#)morse.c 8.1 (Berkeley) 5/31/93"; 4853920Sbillf#endif 4953920Sbillfstatic const char rcsid[] = 5053920Sbillf "$FreeBSD: head/games/morse/morse.c 147110 2005-06-07 19:01:41Z joerg $"; 512490Sjkh#endif /* not lint */ 522490Sjkh 5357527Sjoerg#include <sys/time.h> 5457527Sjoerg 552490Sjkh#include <ctype.h> 5657527Sjoerg#include <fcntl.h> 5778793Sache#include <langinfo.h> 5810352Sjoerg#include <locale.h> 5957527Sjoerg#include <signal.h> 6057527Sjoerg#include <stdio.h> 6110352Sjoerg#include <stdlib.h> 6235857Sjb#include <string.h> 6357527Sjoerg#include <termios.h> 6454622Sbillf#include <unistd.h> 652490Sjkh 6610352Sjoerg#ifdef SPEAKER 6710352Sjoerg#include <machine/speaker.h> 6810352Sjoerg#endif 6910352Sjoerg 7010352Sjoergstruct morsetab { 7110352Sjoerg char inchar; 7210352Sjoerg char *morse; 732490Sjkh}; 742490Sjkh 7554622Sbillfstatic const struct morsetab mtab[] = { 762490Sjkh 7710352Sjoerg /* letters */ 7810352Sjoerg 7954622Sbillf {'a', ".-"}, 8054622Sbillf {'b', "-..."}, 8154622Sbillf {'c', "-.-."}, 8254622Sbillf {'d', "-.."}, 8354622Sbillf {'e', "."}, 8454622Sbillf {'f', "..-."}, 8554622Sbillf {'g', "--."}, 8654622Sbillf {'h', "...."}, 8754622Sbillf {'i', ".."}, 8854622Sbillf {'j', ".---"}, 8954622Sbillf {'k', "-.-"}, 9054622Sbillf {'l', ".-.."}, 9154622Sbillf {'m', "--"}, 9254622Sbillf {'n', "-."}, 9354622Sbillf {'o', "---"}, 9454622Sbillf {'p', ".--."}, 9554622Sbillf {'q', "--.-"}, 9654622Sbillf {'r', ".-."}, 9754622Sbillf {'s', "..."}, 9854622Sbillf {'t', "-"}, 9954622Sbillf {'u', "..-"}, 10054622Sbillf {'v', "...-"}, 10154622Sbillf {'w', ".--"}, 10254622Sbillf {'x', "-..-"}, 10354622Sbillf {'y', "-.--"}, 10454622Sbillf {'z', "--.."}, 10510352Sjoerg 10610352Sjoerg /* digits */ 10710352Sjoerg 10854622Sbillf {'0', "-----"}, 10954622Sbillf {'1', ".----"}, 11054622Sbillf {'2', "..---"}, 11154622Sbillf {'3', "...--"}, 11254622Sbillf {'4', "....-"}, 11354622Sbillf {'5', "....."}, 11454622Sbillf {'6', "-...."}, 11554622Sbillf {'7', "--..."}, 11654622Sbillf {'8', "---.."}, 11754622Sbillf {'9', "----."}, 11810352Sjoerg 11910352Sjoerg /* punctuation */ 12010352Sjoerg 12154622Sbillf {',', "--..--"}, 12254622Sbillf {'.', ".-.-.-"}, 123126040Sfanf {'"', ".-..-."}, 124126040Sfanf {'!', "..--."}, 12554622Sbillf {'?', "..--.."}, 12654622Sbillf {'/', "-..-."}, 12754622Sbillf {'-', "-....-"}, 12854622Sbillf {'=', "-...-"}, /* BT */ 12954622Sbillf {':', "---..."}, 13054622Sbillf {';', "-.-.-."}, 13154622Sbillf {'(', "-.--."}, /* KN */ 13254622Sbillf {')', "-.--.-"}, 13354622Sbillf {'$', "...-..-"}, 13454622Sbillf {'+', ".-.-."}, /* AR */ 135126044Sfanf {'@', ".--.-."}, /* AC */ 13610352Sjoerg 13710352Sjoerg /* prosigns without already assigned values */ 13810352Sjoerg 13954622Sbillf {'#', ".-..."}, /* AS */ 140126040Sfanf {'&', "...-.-"}, /* SK */ 14154622Sbillf {'*', "...-."}, /* VE */ 14254622Sbillf {'%', "-...-.-"}, /* BK */ 14310352Sjoerg 14454622Sbillf {'\0', ""} 14510352Sjoerg}; 14610352Sjoerg 14710352Sjoerg 148129114Sddsstatic const struct morsetab iso8859_1tab[] = { 14954622Sbillf {'�', ".--.-"}, 15054622Sbillf {'�', ".--.-"}, 15154622Sbillf {'�', ".--.-"}, 15254622Sbillf {'�', ".-.-"}, 15354622Sbillf {'�', "-.-.."}, 15454622Sbillf {'�', "..-.."}, 15554622Sbillf {'�', "..-.."}, 15654622Sbillf {'�', "-..-."}, 15754622Sbillf {'�', "---."}, 15854622Sbillf {'�', "..--"}, 15910352Sjoerg 16054622Sbillf {'\0', ""} 16110352Sjoerg}; 16210352Sjoerg 163129114Sddsstatic const struct morsetab iso8859_7tab[] = { 164129114Sdds /* 165129114Sdds * The greek alphabet; you'll need an 8859-7 font in order 166129114Sdds * to see the actual characters. 167129114Sdds * This table does not implement: 168129114Sdds * - the special sequences for the seven diphthongs, 169129114Sdds * - the punctuation differences. 170129114Sdds * Implementing these features would introduce too many 171129114Sdds * special-cases in the program's main loop. 172129114Sdds * The diphtong sequences are: 173129114Sdds * alpha iota .-.- 174129114Sdds * alpha upsilon ..-- 175129114Sdds * epsilon upsilon ---. 176129114Sdds * eta upsilon ...- 177129114Sdds * omikron iota ---.. 178129114Sdds * omikron upsilon ..- 179129114Sdds * upsilon iota .--- 180129114Sdds * The different punctuation symbols are: 181129114Sdds * ; ..-.- 182129114Sdds * ! --..-- 183129114Sdds */ 184129114Sdds {'�', ".-"}, /* alpha */ 185129114Sdds {'�', ".-"}, /* alpha with acute */ 186129114Sdds {'�', "-..."}, /* beta */ 187129114Sdds {'�', "--."}, /* gamma */ 188129114Sdds {'�', "-.."}, /* delta */ 189129114Sdds {'�', "."}, /* epsilon */ 190129114Sdds {'�', "."}, /* epsilon with acute */ 191129114Sdds {'�', "--.."}, /* zeta */ 192129114Sdds {'�', "...."}, /* eta */ 193129114Sdds {'�', "...."}, /* eta with acute */ 194129114Sdds {'�', "-.-."}, /* theta */ 195129114Sdds {'�', ".."}, /* iota */ 196129114Sdds {'�', ".."}, /* iota with acute */ 197129114Sdds {'�', ".."}, /* iota with diairesis */ 198129114Sdds {'�', ".."}, /* iota with acute and diairesis */ 199129114Sdds {'�', "-.-"}, /* kappa */ 200129114Sdds {'�', ".-.."}, /* lamda */ 201129114Sdds {'�', "--"}, /* mu */ 202129114Sdds {'�', "-."}, /* nu */ 203129114Sdds {'�', "-..-"}, /* xi */ 204129114Sdds {'�', "---"}, /* omicron */ 205129114Sdds {'�', "---"}, /* omicron with acute */ 206129114Sdds {'�', ".--."}, /* pi */ 207129114Sdds {'�', ".-."}, /* rho */ 208129114Sdds {'�', "..."}, /* sigma */ 209129114Sdds {'�', "..."}, /* final sigma */ 210129114Sdds {'�', "-"}, /* tau */ 211129114Sdds {'�', "-.--"}, /* upsilon */ 212129114Sdds {'�', "-.--"}, /* upsilon with acute */ 213129114Sdds {'�', "-.--"}, /* upsilon and diairesis */ 214129114Sdds {'�', "-.--"}, /* upsilon with acute and diairesis */ 215129114Sdds {'�', "..-."}, /* phi */ 216129114Sdds {'�', "----"}, /* chi */ 217129114Sdds {'�', "--.-"}, /* psi */ 218129114Sdds {'�', ".--"}, /* omega */ 219129114Sdds {'�', ".--"}, /* omega with acute */ 220129114Sdds 221129114Sdds {'\0', ""} 222129114Sdds}; 223129114Sdds 22454622Sbillfstatic const struct morsetab koi8rtab[] = { 22510352Sjoerg /* 22610352Sjoerg * the cyrillic alphabet; you'll need a KOI8R font in order 22710352Sjoerg * to see the actual characters 22810352Sjoerg */ 22954622Sbillf {'�', ".-"}, /* a */ 23054622Sbillf {'�', "-..."}, /* be */ 23154622Sbillf {'�', ".--"}, /* ve */ 23254622Sbillf {'�', "--."}, /* ge */ 23354622Sbillf {'�', "-.."}, /* de */ 23454622Sbillf {'�', "."}, /* ye */ 23554622Sbillf {'�', "."}, /* yo, the same as ye */ 23654622Sbillf {'�', "...-"}, /* she */ 23754622Sbillf {'�', "--.."}, /* ze */ 23854622Sbillf {'�', ".."}, /* i */ 23954622Sbillf {'�', ".---"}, /* i kratkoye */ 24054622Sbillf {'�', "-.-"}, /* ka */ 24154622Sbillf {'�', ".-.."}, /* el */ 24254622Sbillf {'�', "--"}, /* em */ 24354622Sbillf {'�', "-."}, /* en */ 24454622Sbillf {'�', "---"}, /* o */ 24554622Sbillf {'�', ".--."}, /* pe */ 24654622Sbillf {'�', ".-."}, /* er */ 24754622Sbillf {'�', "..."}, /* es */ 24854622Sbillf {'�', "-"}, /* te */ 24954622Sbillf {'�', "..-"}, /* u */ 25054622Sbillf {'�', "..-."}, /* ef */ 25154622Sbillf {'�', "...."}, /* kha */ 25254622Sbillf {'�', "-.-."}, /* ce */ 25354622Sbillf {'�', "---."}, /* che */ 25454622Sbillf {'�', "----"}, /* sha */ 25554622Sbillf {'�', "--.-"}, /* shcha */ 25654622Sbillf {'�', "-.--"}, /* yi */ 25754622Sbillf {'�', "-..-"}, /* myakhkij znak */ 25854622Sbillf {'�', "..-.."}, /* ae */ 25954622Sbillf {'�', "..--"}, /* yu */ 26054622Sbillf {'�', ".-.-"}, /* ya */ 26110352Sjoerg 26254622Sbillf {'\0', ""} 26310352Sjoerg}; 26410352Sjoerg 26510352Sjoergvoid show(const char *), play(const char *), morse(char); 26657527Sjoergvoid ttyout(const char *); 26757527Sjoergvoid sighandler(int); 26810352Sjoerg 269147110Sjoerg#define GETOPTOPTS "c:d:ef:lsw:" 27057527Sjoerg#define USAGE \ 271147110Sjoerg"usage: morse [-els] [-d device] [-w speed] [-c speed] [-f frequency] [string ...]\n" 27257527Sjoerg 273121945Sphkstatic int pflag, lflag, sflag, eflag; 274147110Sjoergstatic int wpm = 20; /* effective words per minute */ 275147110Sjoergstatic int cpm; /* effective words per minute between 276147110Sjoerg * characters */ 27710352Sjoerg#define FREQUENCY 600 27810352Sjoergstatic int freq = FREQUENCY; 27957527Sjoergstatic char *device; /* for tty-controlled generator */ 28010352Sjoerg 28110352Sjoerg#define DASH_LEN 3 28210352Sjoerg#define CHAR_SPACE 3 28310352Sjoerg#define WORD_SPACE (7 - CHAR_SPACE - 1) 28410352Sjoergstatic float dot_clock; 285147110Sjoergstatic float cdot_clock; 28657527Sjoergint spkr, line; 28757527Sjoergstruct termios otty, ntty; 28857527Sjoergint olflags; 28957527Sjoerg 29057527Sjoerg#ifdef SPEAKER 29110352Sjoergtone_t sound; 29257527Sjoerg#undef GETOPTOPTS 293147110Sjoerg#define GETOPTOPTS "c:d:ef:lpsw:" 29457527Sjoerg#undef USAGE 29557527Sjoerg#define USAGE \ 296147110Sjoerg"usage: morse [-elps] [-d device] [-w speed] [-c speed] [-f frequency] [string ...]\n" 29710352Sjoerg#endif 29810352Sjoerg 29978793Sachestatic const struct morsetab *hightab; 30010352Sjoerg 30110352Sjoergint 30210352Sjoergmain(int argc, char **argv) 3032490Sjkh{ 30457527Sjoerg int ch, lflags; 30578793Sache char *p, *codeset; 3062490Sjkh 30757527Sjoerg while ((ch = getopt(argc, argv, GETOPTOPTS)) != -1) 30810352Sjoerg switch ((char) ch) { 309147110Sjoerg case 'c': 310147110Sjoerg cpm = atoi(optarg); 311147110Sjoerg break; 31257527Sjoerg case 'd': 31357527Sjoerg device = optarg; 31457527Sjoerg break; 31557527Sjoerg case 'e': 31657527Sjoerg eflag = 1; 31757527Sjoerg setvbuf(stdout, 0, _IONBF, 0); 31857527Sjoerg break; 31910352Sjoerg case 'f': 32010352Sjoerg freq = atoi(optarg); 32110352Sjoerg break; 322121945Sphk case 'l': 323121945Sphk lflag = 1; 324121945Sphk break; 32557527Sjoerg#ifdef SPEAKER 32610352Sjoerg case 'p': 32710352Sjoerg pflag = 1; 32810352Sjoerg break; 32957527Sjoerg#endif 3302490Sjkh case 's': 3312490Sjkh sflag = 1; 3322490Sjkh break; 33310352Sjoerg case 'w': 33410352Sjoerg wpm = atoi(optarg); 33510352Sjoerg break; 3362490Sjkh case '?': 3372490Sjkh default: 33857527Sjoerg fputs(USAGE, stderr); 3392490Sjkh exit(1); 3402490Sjkh } 341121945Sphk if (sflag && lflag) { 342121945Sphk fputs("morse: only one of -l and -s allowed\n", stderr); 34310352Sjoerg exit(1); 34410352Sjoerg } 345121945Sphk if ((pflag || device) && (sflag || lflag)) { 346121945Sphk fputs("morse: only one of -p, -d and -l, -s allowed\n", stderr); 347121945Sphk exit(1); 348121945Sphk } 349147110Sjoerg if (cpm == 0) 350147110Sjoerg cpm = wpm; 351147110Sjoerg if ((pflag || device) && ((wpm < 1) || (wpm > 60) || (cpm < 1) || (cpm > 60))) { 35210352Sjoerg fputs("morse: insane speed\n", stderr); 35310352Sjoerg exit(1); 35410352Sjoerg } 35557527Sjoerg if ((pflag || device) && (freq == 0)) 35610352Sjoerg freq = FREQUENCY; 35710352Sjoerg 35810352Sjoerg#ifdef SPEAKER 35910352Sjoerg if (pflag) { 36010352Sjoerg if ((spkr = open(SPEAKER, O_WRONLY, 0)) == -1) { 36110352Sjoerg perror(SPEAKER); 36210352Sjoerg exit(1); 36310352Sjoerg } 36457527Sjoerg } else 36557527Sjoerg#endif 36657527Sjoerg if (device) { 36757527Sjoerg if ((line = open(device, O_WRONLY | O_NONBLOCK)) == -1) { 36857527Sjoerg perror("open tty line"); 36957527Sjoerg exit(1); 37057527Sjoerg } 37157527Sjoerg if (tcgetattr(line, &otty) == -1) { 37257527Sjoerg perror("tcgetattr() failed"); 37357527Sjoerg exit(1); 37457527Sjoerg } 37557527Sjoerg ntty = otty; 37657527Sjoerg ntty.c_cflag |= CLOCAL; 37757527Sjoerg tcsetattr(line, TCSANOW, &ntty); 37857527Sjoerg lflags = fcntl(line, F_GETFL); 37957527Sjoerg lflags &= ~O_NONBLOCK; 38057527Sjoerg fcntl(line, F_SETFL, &lflags); 38157527Sjoerg ioctl(line, TIOCMGET, &lflags); 38257527Sjoerg lflags &= ~TIOCM_RTS; 38357527Sjoerg olflags = lflags; 38457527Sjoerg ioctl(line, TIOCMSET, &lflags); 38557527Sjoerg (void)signal(SIGHUP, sighandler); 38657527Sjoerg (void)signal(SIGINT, sighandler); 38757527Sjoerg (void)signal(SIGQUIT, sighandler); 38857527Sjoerg (void)signal(SIGTERM, sighandler); 38957527Sjoerg } 39057527Sjoerg if (pflag || device) { 39110352Sjoerg dot_clock = wpm / 2.4; /* dots/sec */ 39210352Sjoerg dot_clock = 1 / dot_clock; /* duration of a dot */ 39310352Sjoerg dot_clock = dot_clock / 2; /* dot_clock runs at twice */ 39410352Sjoerg /* the dot rate */ 39510352Sjoerg dot_clock = dot_clock * 100; /* scale for ioctl */ 396147110Sjoerg 397147110Sjoerg cdot_clock = cpm / 2.4; /* dots/sec */ 398147110Sjoerg cdot_clock = 1 / cdot_clock; /* duration of a dot */ 399147110Sjoerg cdot_clock = cdot_clock / 2; /* dot_clock runs at twice */ 400147110Sjoerg /* the dot rate */ 401147110Sjoerg cdot_clock = cdot_clock * 100; /* scale for ioctl */ 40210352Sjoerg } 40357527Sjoerg 4042490Sjkh argc -= optind; 4052490Sjkh argv += optind; 4062490Sjkh 40778793Sache if (setlocale(LC_CTYPE, "") != NULL && 40878793Sache *(codeset = nl_langinfo(CODESET)) != '\0') { 40978793Sache if (strcmp(codeset, "KOI8-R") == 0) 41010352Sjoerg hightab = koi8rtab; 41178793Sache else if (strcmp(codeset, "ISO8859-1") == 0 || 41278793Sache strcmp(codeset, "ISO8859-15") == 0) 413129114Sdds hightab = iso8859_1tab; 414129114Sdds else if (strcmp(codeset, "ISO8859-7") == 0) 415129114Sdds hightab = iso8859_7tab; 41610352Sjoerg } 41710352Sjoerg 418121945Sphk if (lflag) 419121945Sphk printf("m"); 42010352Sjoerg if (*argv) { 4212490Sjkh do { 42210352Sjoerg for (p = *argv; *p; ++p) { 42357527Sjoerg if (eflag) 42457527Sjoerg putchar(*p); 42529018Sache morse(*p); 42610352Sjoerg } 42757527Sjoerg if (eflag) 42857527Sjoerg putchar(' '); 42929018Sache morse(' '); 4302490Sjkh } while (*++argv); 43110352Sjoerg } else { 43257527Sjoerg while ((ch = getchar()) != EOF) { 43357527Sjoerg if (eflag) 43457527Sjoerg putchar(ch); 43510352Sjoerg morse(ch); 43657527Sjoerg } 43710352Sjoerg } 43857527Sjoerg if (device) 43957527Sjoerg tcsetattr(line, TCSANOW, &otty); 44010352Sjoerg exit(0); 4412490Sjkh} 4422490Sjkh 44310352Sjoergvoid 44410352Sjoergmorse(char c) 4452490Sjkh{ 44654622Sbillf const struct morsetab *m; 44710352Sjoerg 44829018Sache if (isalpha((unsigned char)c)) 44929018Sache c = tolower((unsigned char)c); 45010352Sjoerg if ((c == '\r') || (c == '\n')) 45110352Sjoerg c = ' '; 45210352Sjoerg if (c == ' ') { 453121945Sphk if (pflag) 45410352Sjoerg play(" "); 455121945Sphk else if (device) 45657527Sjoerg ttyout(" "); 457121945Sphk else if (lflag) 458121945Sphk printf("\n"); 459121945Sphk else 46010352Sjoerg show(""); 461121945Sphk return; 46210352Sjoerg } 46310352Sjoerg for (m = ((unsigned char)c < 0x80? mtab: hightab); 46478793Sache m != NULL && m->inchar != '\0'; 46510352Sjoerg m++) { 46610352Sjoerg if (m->inchar == c) { 46710352Sjoerg if (pflag) { 46810352Sjoerg play(m->morse); 46957527Sjoerg } else if (device) { 47057527Sjoerg ttyout(m->morse); 47110352Sjoerg } else 47210352Sjoerg show(m->morse); 47310352Sjoerg } 47410352Sjoerg } 4752490Sjkh} 4762490Sjkh 47710352Sjoergvoid 47810352Sjoergshow(const char *s) 4792490Sjkh{ 480121945Sphk if (lflag) { 481121945Sphk printf("%s ", s); 482121945Sphk } else if (sflag) { 483121945Sphk printf(" %s\n", s); 484121945Sphk } else { 48510352Sjoerg for (; *s; ++s) 48610352Sjoerg printf(" %s", *s == '.' ? "dit" : "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