morse.c revision 203921
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/* 35179654Sscf * Taught to send *real* morse by Lyndon Nerenberg (VE6BBM) 36179654Sscf * <lyndon@orthanc.ca> 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 203921 2010-02-15 14:31:05Z uqs $"; 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 66203479Simp/* Always use the speaker, let the open fail if -p is selected */ 67203479Simp#define SPEAKER "/dev/speaker" 68203479Simp 6910352Sjoerg#ifdef SPEAKER 70152306Sru#include <dev/speaker/speaker.h> 7110352Sjoerg#endif 7210352Sjoerg 7310352Sjoergstruct morsetab { 74203921Suqs const char inchar; 75203921Suqs const char *morse; 762490Sjkh}; 772490Sjkh 7854622Sbillfstatic const struct morsetab mtab[] = { 792490Sjkh 8010352Sjoerg /* letters */ 8110352Sjoerg 8254622Sbillf {'a', ".-"}, 8354622Sbillf {'b', "-..."}, 8454622Sbillf {'c', "-.-."}, 8554622Sbillf {'d', "-.."}, 8654622Sbillf {'e', "."}, 8754622Sbillf {'f', "..-."}, 8854622Sbillf {'g', "--."}, 8954622Sbillf {'h', "...."}, 9054622Sbillf {'i', ".."}, 9154622Sbillf {'j', ".---"}, 9254622Sbillf {'k', "-.-"}, 9354622Sbillf {'l', ".-.."}, 9454622Sbillf {'m', "--"}, 9554622Sbillf {'n', "-."}, 9654622Sbillf {'o', "---"}, 9754622Sbillf {'p', ".--."}, 9854622Sbillf {'q', "--.-"}, 9954622Sbillf {'r', ".-."}, 10054622Sbillf {'s', "..."}, 10154622Sbillf {'t', "-"}, 10254622Sbillf {'u', "..-"}, 10354622Sbillf {'v', "...-"}, 10454622Sbillf {'w', ".--"}, 10554622Sbillf {'x', "-..-"}, 10654622Sbillf {'y', "-.--"}, 10754622Sbillf {'z', "--.."}, 10810352Sjoerg 10910352Sjoerg /* digits */ 11010352Sjoerg 11154622Sbillf {'0', "-----"}, 11254622Sbillf {'1', ".----"}, 11354622Sbillf {'2', "..---"}, 11454622Sbillf {'3', "...--"}, 11554622Sbillf {'4', "....-"}, 11654622Sbillf {'5', "....."}, 11754622Sbillf {'6', "-...."}, 11854622Sbillf {'7', "--..."}, 11954622Sbillf {'8', "---.."}, 12054622Sbillf {'9', "----."}, 12110352Sjoerg 12210352Sjoerg /* punctuation */ 12310352Sjoerg 12454622Sbillf {',', "--..--"}, 12554622Sbillf {'.', ".-.-.-"}, 126126040Sfanf {'"', ".-..-."}, 127126040Sfanf {'!', "..--."}, 12854622Sbillf {'?', "..--.."}, 12954622Sbillf {'/', "-..-."}, 13054622Sbillf {'-', "-....-"}, 13154622Sbillf {'=', "-...-"}, /* BT */ 13254622Sbillf {':', "---..."}, 13354622Sbillf {';', "-.-.-."}, 13454622Sbillf {'(', "-.--."}, /* KN */ 13554622Sbillf {')', "-.--.-"}, 13654622Sbillf {'$', "...-..-"}, 13754622Sbillf {'+', ".-.-."}, /* AR */ 138126044Sfanf {'@', ".--.-."}, /* AC */ 13910352Sjoerg 14010352Sjoerg /* prosigns without already assigned values */ 14110352Sjoerg 14254622Sbillf {'#', ".-..."}, /* AS */ 143126040Sfanf {'&', "...-.-"}, /* SK */ 14454622Sbillf {'*', "...-."}, /* VE */ 14554622Sbillf {'%', "-...-.-"}, /* BK */ 14610352Sjoerg 14754622Sbillf {'\0', ""} 14810352Sjoerg}; 14910352Sjoerg 15010352Sjoerg 151129114Sddsstatic const struct morsetab iso8859_1tab[] = { 15254622Sbillf {'�', ".--.-"}, 15354622Sbillf {'�', ".--.-"}, 15454622Sbillf {'�', ".--.-"}, 15554622Sbillf {'�', ".-.-"}, 15654622Sbillf {'�', "-.-.."}, 15754622Sbillf {'�', "..-.."}, 15854622Sbillf {'�', "..-.."}, 15954622Sbillf {'�', "-..-."}, 16054622Sbillf {'�', "---."}, 16154622Sbillf {'�', "..--"}, 16210352Sjoerg 16354622Sbillf {'\0', ""} 16410352Sjoerg}; 16510352Sjoerg 166129114Sddsstatic const struct morsetab iso8859_7tab[] = { 167129114Sdds /* 168129114Sdds * The greek alphabet; you'll need an 8859-7 font in order 169129114Sdds * to see the actual characters. 170129114Sdds * This table does not implement: 171129114Sdds * - the special sequences for the seven diphthongs, 172129114Sdds * - the punctuation differences. 173129114Sdds * Implementing these features would introduce too many 174129114Sdds * special-cases in the program's main loop. 175129114Sdds * The diphtong sequences are: 176129114Sdds * alpha iota .-.- 177129114Sdds * alpha upsilon ..-- 178129114Sdds * epsilon upsilon ---. 179129114Sdds * eta upsilon ...- 180129114Sdds * omikron iota ---.. 181129114Sdds * omikron upsilon ..- 182129114Sdds * upsilon iota .--- 183129114Sdds * The different punctuation symbols are: 184129114Sdds * ; ..-.- 185129114Sdds * ! --..-- 186129114Sdds */ 187129114Sdds {'�', ".-"}, /* alpha */ 188129114Sdds {'�', ".-"}, /* alpha with acute */ 189129114Sdds {'�', "-..."}, /* beta */ 190129114Sdds {'�', "--."}, /* gamma */ 191129114Sdds {'�', "-.."}, /* delta */ 192129114Sdds {'�', "."}, /* epsilon */ 193129114Sdds {'�', "."}, /* epsilon with acute */ 194129114Sdds {'�', "--.."}, /* zeta */ 195129114Sdds {'�', "...."}, /* eta */ 196129114Sdds {'�', "...."}, /* eta with acute */ 197129114Sdds {'�', "-.-."}, /* theta */ 198129114Sdds {'�', ".."}, /* iota */ 199129114Sdds {'�', ".."}, /* iota with acute */ 200129114Sdds {'�', ".."}, /* iota with diairesis */ 201129114Sdds {'�', ".."}, /* iota with acute and diairesis */ 202129114Sdds {'�', "-.-"}, /* kappa */ 203129114Sdds {'�', ".-.."}, /* lamda */ 204129114Sdds {'�', "--"}, /* mu */ 205129114Sdds {'�', "-."}, /* nu */ 206129114Sdds {'�', "-..-"}, /* xi */ 207129114Sdds {'�', "---"}, /* omicron */ 208129114Sdds {'�', "---"}, /* omicron with acute */ 209129114Sdds {'�', ".--."}, /* pi */ 210129114Sdds {'�', ".-."}, /* rho */ 211129114Sdds {'�', "..."}, /* sigma */ 212129114Sdds {'�', "..."}, /* final sigma */ 213129114Sdds {'�', "-"}, /* tau */ 214129114Sdds {'�', "-.--"}, /* upsilon */ 215129114Sdds {'�', "-.--"}, /* upsilon with acute */ 216129114Sdds {'�', "-.--"}, /* upsilon and diairesis */ 217129114Sdds {'�', "-.--"}, /* upsilon with acute and diairesis */ 218129114Sdds {'�', "..-."}, /* phi */ 219129114Sdds {'�', "----"}, /* chi */ 220129114Sdds {'�', "--.-"}, /* psi */ 221129114Sdds {'�', ".--"}, /* omega */ 222129114Sdds {'�', ".--"}, /* omega with acute */ 223129114Sdds 224129114Sdds {'\0', ""} 225129114Sdds}; 226129114Sdds 22754622Sbillfstatic const struct morsetab koi8rtab[] = { 22810352Sjoerg /* 22910352Sjoerg * the cyrillic alphabet; you'll need a KOI8R font in order 23010352Sjoerg * to see the actual characters 23110352Sjoerg */ 23254622Sbillf {'�', ".-"}, /* a */ 23354622Sbillf {'�', "-..."}, /* be */ 23454622Sbillf {'�', ".--"}, /* ve */ 23554622Sbillf {'�', "--."}, /* ge */ 23654622Sbillf {'�', "-.."}, /* de */ 23754622Sbillf {'�', "."}, /* ye */ 23854622Sbillf {'�', "."}, /* yo, the same as ye */ 23954622Sbillf {'�', "...-"}, /* she */ 24054622Sbillf {'�', "--.."}, /* ze */ 24154622Sbillf {'�', ".."}, /* i */ 24254622Sbillf {'�', ".---"}, /* i kratkoye */ 24354622Sbillf {'�', "-.-"}, /* ka */ 24454622Sbillf {'�', ".-.."}, /* el */ 24554622Sbillf {'�', "--"}, /* em */ 24654622Sbillf {'�', "-."}, /* en */ 24754622Sbillf {'�', "---"}, /* o */ 24854622Sbillf {'�', ".--."}, /* pe */ 24954622Sbillf {'�', ".-."}, /* er */ 25054622Sbillf {'�', "..."}, /* es */ 25154622Sbillf {'�', "-"}, /* te */ 25254622Sbillf {'�', "..-"}, /* u */ 25354622Sbillf {'�', "..-."}, /* ef */ 25454622Sbillf {'�', "...."}, /* kha */ 25554622Sbillf {'�', "-.-."}, /* ce */ 25654622Sbillf {'�', "---."}, /* che */ 25754622Sbillf {'�', "----"}, /* sha */ 25854622Sbillf {'�', "--.-"}, /* shcha */ 25954622Sbillf {'�', "-.--"}, /* yi */ 26054622Sbillf {'�', "-..-"}, /* myakhkij znak */ 26154622Sbillf {'�', "..-.."}, /* ae */ 26254622Sbillf {'�', "..--"}, /* yu */ 26354622Sbillf {'�', ".-.-"}, /* ya */ 26410352Sjoerg 26554622Sbillf {'\0', ""} 26610352Sjoerg}; 26710352Sjoerg 26810352Sjoergvoid show(const char *), play(const char *), morse(char); 26957527Sjoergvoid ttyout(const char *); 27057527Sjoergvoid sighandler(int); 27110352Sjoerg 272147110Sjoerg#define GETOPTOPTS "c:d:ef:lsw:" 27357527Sjoerg#define USAGE \ 274147110Sjoerg"usage: morse [-els] [-d device] [-w speed] [-c speed] [-f frequency] [string ...]\n" 27557527Sjoerg 276121945Sphkstatic int pflag, lflag, sflag, eflag; 277147110Sjoergstatic int wpm = 20; /* effective words per minute */ 278147110Sjoergstatic int cpm; /* effective words per minute between 279147110Sjoerg * characters */ 28010352Sjoerg#define FREQUENCY 600 28110352Sjoergstatic int freq = FREQUENCY; 28257527Sjoergstatic char *device; /* for tty-controlled generator */ 28310352Sjoerg 28410352Sjoerg#define DASH_LEN 3 28510352Sjoerg#define CHAR_SPACE 3 28610352Sjoerg#define WORD_SPACE (7 - CHAR_SPACE - 1) 28710352Sjoergstatic float dot_clock; 288147110Sjoergstatic float cdot_clock; 28957527Sjoergint spkr, line; 29057527Sjoergstruct termios otty, ntty; 29157527Sjoergint olflags; 29257527Sjoerg 29357527Sjoerg#ifdef SPEAKER 29410352Sjoergtone_t sound; 29557527Sjoerg#undef GETOPTOPTS 296147110Sjoerg#define GETOPTOPTS "c:d:ef:lpsw:" 29757527Sjoerg#undef USAGE 29857527Sjoerg#define USAGE \ 299147110Sjoerg"usage: morse [-elps] [-d device] [-w speed] [-c speed] [-f frequency] [string ...]\n" 30010352Sjoerg#endif 30110352Sjoerg 30278793Sachestatic const struct morsetab *hightab; 30310352Sjoerg 30410352Sjoergint 30510352Sjoergmain(int argc, char **argv) 3062490Sjkh{ 30757527Sjoerg int ch, lflags; 30878793Sache char *p, *codeset; 3092490Sjkh 31057527Sjoerg while ((ch = getopt(argc, argv, GETOPTOPTS)) != -1) 31110352Sjoerg switch ((char) ch) { 312147110Sjoerg case 'c': 313147110Sjoerg cpm = atoi(optarg); 314147110Sjoerg break; 31557527Sjoerg case 'd': 31657527Sjoerg device = optarg; 31757527Sjoerg break; 31857527Sjoerg case 'e': 31957527Sjoerg eflag = 1; 32057527Sjoerg setvbuf(stdout, 0, _IONBF, 0); 32157527Sjoerg break; 32210352Sjoerg case 'f': 32310352Sjoerg freq = atoi(optarg); 32410352Sjoerg break; 325121945Sphk case 'l': 326121945Sphk lflag = 1; 327121945Sphk break; 32857527Sjoerg#ifdef SPEAKER 32910352Sjoerg case 'p': 33010352Sjoerg pflag = 1; 33110352Sjoerg break; 33257527Sjoerg#endif 3332490Sjkh case 's': 3342490Sjkh sflag = 1; 3352490Sjkh break; 33610352Sjoerg case 'w': 33710352Sjoerg wpm = atoi(optarg); 33810352Sjoerg break; 3392490Sjkh case '?': 3402490Sjkh default: 34157527Sjoerg fputs(USAGE, stderr); 3422490Sjkh exit(1); 3432490Sjkh } 344121945Sphk if (sflag && lflag) { 345121945Sphk fputs("morse: only one of -l and -s allowed\n", stderr); 34610352Sjoerg exit(1); 34710352Sjoerg } 348121945Sphk if ((pflag || device) && (sflag || lflag)) { 349121945Sphk fputs("morse: only one of -p, -d and -l, -s allowed\n", stderr); 350121945Sphk exit(1); 351121945Sphk } 352147110Sjoerg if (cpm == 0) 353147110Sjoerg cpm = wpm; 354147110Sjoerg if ((pflag || device) && ((wpm < 1) || (wpm > 60) || (cpm < 1) || (cpm > 60))) { 35510352Sjoerg fputs("morse: insane speed\n", stderr); 35610352Sjoerg exit(1); 35710352Sjoerg } 35857527Sjoerg if ((pflag || device) && (freq == 0)) 35910352Sjoerg freq = FREQUENCY; 36010352Sjoerg 36110352Sjoerg#ifdef SPEAKER 36210352Sjoerg if (pflag) { 36310352Sjoerg if ((spkr = open(SPEAKER, O_WRONLY, 0)) == -1) { 36410352Sjoerg perror(SPEAKER); 36510352Sjoerg exit(1); 36610352Sjoerg } 36757527Sjoerg } else 36857527Sjoerg#endif 36957527Sjoerg if (device) { 37057527Sjoerg if ((line = open(device, O_WRONLY | O_NONBLOCK)) == -1) { 37157527Sjoerg perror("open tty line"); 37257527Sjoerg exit(1); 37357527Sjoerg } 37457527Sjoerg if (tcgetattr(line, &otty) == -1) { 37557527Sjoerg perror("tcgetattr() failed"); 37657527Sjoerg exit(1); 37757527Sjoerg } 37857527Sjoerg ntty = otty; 37957527Sjoerg ntty.c_cflag |= CLOCAL; 38057527Sjoerg tcsetattr(line, TCSANOW, &ntty); 38157527Sjoerg lflags = fcntl(line, F_GETFL); 38257527Sjoerg lflags &= ~O_NONBLOCK; 38357527Sjoerg fcntl(line, F_SETFL, &lflags); 38457527Sjoerg ioctl(line, TIOCMGET, &lflags); 38557527Sjoerg lflags &= ~TIOCM_RTS; 38657527Sjoerg olflags = lflags; 38757527Sjoerg ioctl(line, TIOCMSET, &lflags); 38857527Sjoerg (void)signal(SIGHUP, sighandler); 38957527Sjoerg (void)signal(SIGINT, sighandler); 39057527Sjoerg (void)signal(SIGQUIT, sighandler); 39157527Sjoerg (void)signal(SIGTERM, sighandler); 39257527Sjoerg } 39357527Sjoerg if (pflag || device) { 39410352Sjoerg dot_clock = wpm / 2.4; /* dots/sec */ 39510352Sjoerg dot_clock = 1 / dot_clock; /* duration of a dot */ 39610352Sjoerg dot_clock = dot_clock / 2; /* dot_clock runs at twice */ 39710352Sjoerg /* the dot rate */ 39810352Sjoerg dot_clock = dot_clock * 100; /* scale for ioctl */ 399147110Sjoerg 400147110Sjoerg cdot_clock = cpm / 2.4; /* dots/sec */ 401147110Sjoerg cdot_clock = 1 / cdot_clock; /* duration of a dot */ 402147110Sjoerg cdot_clock = cdot_clock / 2; /* dot_clock runs at twice */ 403147110Sjoerg /* the dot rate */ 404147110Sjoerg cdot_clock = cdot_clock * 100; /* scale for ioctl */ 40510352Sjoerg } 40657527Sjoerg 4072490Sjkh argc -= optind; 4082490Sjkh argv += optind; 4092490Sjkh 41078793Sache if (setlocale(LC_CTYPE, "") != NULL && 41178793Sache *(codeset = nl_langinfo(CODESET)) != '\0') { 41278793Sache if (strcmp(codeset, "KOI8-R") == 0) 41310352Sjoerg hightab = koi8rtab; 41478793Sache else if (strcmp(codeset, "ISO8859-1") == 0 || 41578793Sache strcmp(codeset, "ISO8859-15") == 0) 416129114Sdds hightab = iso8859_1tab; 417129114Sdds else if (strcmp(codeset, "ISO8859-7") == 0) 418129114Sdds hightab = iso8859_7tab; 41910352Sjoerg } 42010352Sjoerg 421121945Sphk if (lflag) 422121945Sphk printf("m"); 42310352Sjoerg if (*argv) { 4242490Sjkh do { 42510352Sjoerg for (p = *argv; *p; ++p) { 42657527Sjoerg if (eflag) 42757527Sjoerg putchar(*p); 42829018Sache morse(*p); 42910352Sjoerg } 43057527Sjoerg if (eflag) 43157527Sjoerg putchar(' '); 43229018Sache morse(' '); 4332490Sjkh } while (*++argv); 43410352Sjoerg } else { 43557527Sjoerg while ((ch = getchar()) != EOF) { 43657527Sjoerg if (eflag) 43757527Sjoerg putchar(ch); 43810352Sjoerg morse(ch); 43957527Sjoerg } 44010352Sjoerg } 44157527Sjoerg if (device) 44257527Sjoerg tcsetattr(line, TCSANOW, &otty); 44310352Sjoerg exit(0); 4442490Sjkh} 4452490Sjkh 44610352Sjoergvoid 44710352Sjoergmorse(char c) 4482490Sjkh{ 44954622Sbillf const struct morsetab *m; 45010352Sjoerg 45129018Sache if (isalpha((unsigned char)c)) 45229018Sache c = tolower((unsigned char)c); 45310352Sjoerg if ((c == '\r') || (c == '\n')) 45410352Sjoerg c = ' '; 45510352Sjoerg if (c == ' ') { 456121945Sphk if (pflag) 45710352Sjoerg play(" "); 458121945Sphk else if (device) 45957527Sjoerg ttyout(" "); 460121945Sphk else if (lflag) 461121945Sphk printf("\n"); 462121945Sphk else 46310352Sjoerg show(""); 464121945Sphk return; 46510352Sjoerg } 46610352Sjoerg for (m = ((unsigned char)c < 0x80? mtab: hightab); 46778793Sache m != NULL && m->inchar != '\0'; 46810352Sjoerg m++) { 46910352Sjoerg if (m->inchar == c) { 47010352Sjoerg if (pflag) { 47110352Sjoerg play(m->morse); 47257527Sjoerg } else if (device) { 47357527Sjoerg ttyout(m->morse); 47410352Sjoerg } else 47510352Sjoerg show(m->morse); 47610352Sjoerg } 47710352Sjoerg } 4782490Sjkh} 4792490Sjkh 48010352Sjoergvoid 48110352Sjoergshow(const char *s) 4822490Sjkh{ 483121945Sphk if (lflag) { 484121945Sphk printf("%s ", s); 485121945Sphk } else if (sflag) { 486121945Sphk printf(" %s\n", s); 487121945Sphk } else { 48810352Sjoerg for (; *s; ++s) 489179654Sscf printf(" %s", *s == '.' ? *(s + 1) == '\0' ? "dit" : 490179654Sscf "di" : "dah"); 491121945Sphk printf("\n"); 492121945Sphk } 4932490Sjkh} 49410352Sjoerg 49510352Sjoergvoid 49610352Sjoergplay(const char *s) 49710352Sjoerg{ 49810352Sjoerg#ifdef SPEAKER 49910352Sjoerg const char *c; 50010352Sjoerg 50110352Sjoerg for (c = s; *c != '\0'; c++) { 50229018Sache switch (*c) { 50310352Sjoerg case '.': 50410352Sjoerg sound.frequency = freq; 50510352Sjoerg sound.duration = dot_clock; 50610352Sjoerg break; 50710352Sjoerg case '-': 50810352Sjoerg sound.frequency = freq; 50910352Sjoerg sound.duration = dot_clock * DASH_LEN; 51010352Sjoerg break; 51110352Sjoerg case ' ': 51210352Sjoerg sound.frequency = 0; 513147110Sjoerg sound.duration = cdot_clock * WORD_SPACE; 51410352Sjoerg break; 51510352Sjoerg default: 51610352Sjoerg sound.duration = 0; 51710352Sjoerg } 51810352Sjoerg if (sound.duration) { 51910352Sjoerg if (ioctl(spkr, SPKRTONE, &sound) == -1) { 52010352Sjoerg perror("ioctl play"); 52110352Sjoerg exit(1); 52210352Sjoerg } 52310352Sjoerg } 52410352Sjoerg sound.frequency = 0; 52510352Sjoerg sound.duration = dot_clock; 52610352Sjoerg if (ioctl(spkr, SPKRTONE, &sound) == -1) { 52710352Sjoerg perror("ioctl rest"); 52810352Sjoerg exit(1); 52910352Sjoerg } 53010352Sjoerg } 53110352Sjoerg sound.frequency = 0; 532147110Sjoerg sound.duration = cdot_clock * CHAR_SPACE; 53310352Sjoerg ioctl(spkr, SPKRTONE, &sound); 53410352Sjoerg#endif 53510352Sjoerg} 53657527Sjoerg 53757527Sjoergvoid 53857527Sjoergttyout(const char *s) 53957527Sjoerg{ 54057527Sjoerg const char *c; 54157527Sjoerg int duration, on, lflags; 54257527Sjoerg 54357527Sjoerg for (c = s; *c != '\0'; c++) { 54457527Sjoerg switch (*c) { 54557527Sjoerg case '.': 54657527Sjoerg on = 1; 54757527Sjoerg duration = dot_clock; 54857527Sjoerg break; 54957527Sjoerg case '-': 55057527Sjoerg on = 1; 55157527Sjoerg duration = dot_clock * DASH_LEN; 55257527Sjoerg break; 55357527Sjoerg case ' ': 55457527Sjoerg on = 0; 555147110Sjoerg duration = cdot_clock * WORD_SPACE; 55657527Sjoerg break; 55757527Sjoerg default: 55857527Sjoerg on = 0; 55957527Sjoerg duration = 0; 56057527Sjoerg } 56157527Sjoerg if (on) { 56257527Sjoerg ioctl(line, TIOCMGET, &lflags); 56357527Sjoerg lflags |= TIOCM_RTS; 56457527Sjoerg ioctl(line, TIOCMSET, &lflags); 56557527Sjoerg } 56657527Sjoerg duration *= 10000; 56757527Sjoerg if (duration) 56857527Sjoerg usleep(duration); 56957527Sjoerg ioctl(line, TIOCMGET, &lflags); 57057527Sjoerg lflags &= ~TIOCM_RTS; 57157527Sjoerg ioctl(line, TIOCMSET, &lflags); 57257527Sjoerg duration = dot_clock * 10000; 57357527Sjoerg usleep(duration); 57457527Sjoerg } 575147110Sjoerg duration = cdot_clock * CHAR_SPACE * 10000; 57657527Sjoerg usleep(duration); 57757527Sjoerg} 57857527Sjoerg 57957527Sjoergvoid 58057527Sjoergsighandler(int signo) 58157527Sjoerg{ 58257527Sjoerg 58357527Sjoerg ioctl(line, TIOCMSET, &olflags); 58457527Sjoerg tcsetattr(line, TCSANOW, &otty); 58557527Sjoerg 58657527Sjoerg signal(signo, SIG_DFL); 58757527Sjoerg (void)kill(getpid(), signo); 58857527Sjoerg} 589