morse.c revision 129299
1249109Sjkim/* 2249109Sjkim * Copyright (c) 1988, 1993 3249109Sjkim * The Regents of the University of California. All rights reserved. 4249109Sjkim * 5249109Sjkim * Redistribution and use in source and binary forms, with or without 6249109Sjkim * modification, are permitted provided that the following conditions 7249109Sjkim * are met: 8306536Sjkim * 1. Redistributions of source code must retain the above copyright 9249109Sjkim * notice, this list of conditions and the following disclaimer. 10249109Sjkim * 2. Redistributions in binary form must reproduce the above copyright 11249109Sjkim * notice, this list of conditions and the following disclaimer in the 12249109Sjkim * documentation and/or other materials provided with the distribution. 13249109Sjkim * 3. All advertising materials mentioning features or use of this software 14249109Sjkim * must display the following acknowledgement: 15249109Sjkim * This product includes software developed by the University of 16249109Sjkim * California, Berkeley and its contributors. 17249109Sjkim * 4. Neither the name of the University nor the names of its contributors 18249109Sjkim * may be used to endorse or promote products derived from this software 19249109Sjkim * without specific prior written permission. 20249109Sjkim * 21249109Sjkim * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22249109Sjkim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23249109Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24249109Sjkim * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25249109Sjkim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26249109Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27249109Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28249109Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29249109Sjkim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30249109Sjkim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31249109Sjkim * SUCH DAMAGE. 32249109Sjkim */ 33249109Sjkim 34249109Sjkim/* 35249109Sjkim * Taught to send *real* morse by Lyndon Nerenberg (VE7TCP/VE6BBM) 36249109Sjkim * <lyndon@orthanc.com> 37249109Sjkim */ 38249109Sjkim 39249109Sjkim#ifndef lint 40249109Sjkimstatic const char copyright[] = 41249109Sjkim"@(#) Copyright (c) 1988, 1993\n\ 42249109Sjkim The Regents of the University of California. All rights reserved.\n"; 43249109Sjkim#endif /* not lint */ 44249112Sjkim 45249109Sjkim#ifndef lint 46249112Sjkim#if 0 47249112Sjkimstatic char sccsid[] = "@(#)morse.c 8.1 (Berkeley) 5/31/93"; 48249109Sjkim#endif 49249109Sjkimstatic const char rcsid[] = 50249109Sjkim "$FreeBSD: head/games/morse/morse.c 129299 2004-05-16 21:49:23Z ru $"; 51249109Sjkim#endif /* not lint */ 52249109Sjkim 53249109Sjkim#include <sys/time.h> 54249109Sjkim 55249109Sjkim#include <ctype.h> 56249109Sjkim#include <fcntl.h> 57249109Sjkim#include <langinfo.h> 58249109Sjkim#include <locale.h> 59249109Sjkim#include <signal.h> 60253690Sjkim#include <stdio.h> 61249109Sjkim#include <stdlib.h> 62249109Sjkim#include <string.h> 63249109Sjkim#include <termios.h> 64253690Sjkim#include <unistd.h> 65253690Sjkim 66249109Sjkim#ifdef SPEAKER 67249109Sjkim#include <machine/speaker.h> 68249109Sjkim#endif 69249109Sjkim 70249109Sjkimstruct morsetab { 71249109Sjkim char inchar; 72249109Sjkim char *morse; 73249109Sjkim}; 74249109Sjkim 75249109Sjkimstatic const struct morsetab mtab[] = { 76249109Sjkim 77249109Sjkim /* letters */ 78249109Sjkim 79249109Sjkim {'a', ".-"}, 80249109Sjkim {'b', "-..."}, 81250838Sjkim {'c', "-.-."}, 82250838Sjkim {'d', "-.."}, 83250838Sjkim {'e', "."}, 84249109Sjkim {'f', "..-."}, 85249109Sjkim {'g', "--."}, 86249109Sjkim {'h', "...."}, 87249109Sjkim {'i', ".."}, 88249109Sjkim {'j', ".---"}, 89249109Sjkim {'k', "-.-"}, 90249109Sjkim {'l', ".-.."}, 91249109Sjkim {'m', "--"}, 92249109Sjkim {'n', "-."}, 93249109Sjkim {'o', "---"}, 94249109Sjkim {'p', ".--."}, 95249109Sjkim {'q', "--.-"}, 96249109Sjkim {'r', ".-."}, 97249109Sjkim {'s', "..."}, 98249109Sjkim {'t', "-"}, 99253690Sjkim {'u', "..-"}, 100253690Sjkim {'v', "...-"}, 101250838Sjkim {'w', ".--"}, 102249109Sjkim {'x', "-..-"}, 103249109Sjkim {'y', "-.--"}, 104249109Sjkim {'z', "--.."}, 105249109Sjkim 106249109Sjkim /* digits */ 107249109Sjkim 108249109Sjkim {'0', "-----"}, 109249109Sjkim {'1', ".----"}, 110249109Sjkim {'2', "..---"}, 111249109Sjkim {'3', "...--"}, 112249109Sjkim {'4', "....-"}, 113249109Sjkim {'5', "....."}, 114249109Sjkim {'6', "-...."}, 115249109Sjkim {'7', "--..."}, 116249109Sjkim {'8', "---.."}, 117249109Sjkim {'9', "----."}, 118249109Sjkim 119249109Sjkim /* punctuation */ 120249109Sjkim 121249109Sjkim {',', "--..--"}, 122249109Sjkim {'.', ".-.-.-"}, 123249109Sjkim {'"', ".-..-."}, 124249109Sjkim {'!', "..--."}, 125253690Sjkim {'?', "..--.."}, 126253690Sjkim {'/', "-..-."}, 127253690Sjkim {'-', "-....-"}, 128250838Sjkim {'=', "-...-"}, /* BT */ 129250838Sjkim {':', "---..."}, 130249109Sjkim {';', "-.-.-."}, 131249109Sjkim {'(', "-.--."}, /* KN */ 132250838Sjkim {')', "-.--.-"}, 133250838Sjkim {'$', "...-..-"}, 134250838Sjkim {'+', ".-.-."}, /* AR */ 135249109Sjkim {'@', ".--.-."}, /* AC */ 136250838Sjkim 137250838Sjkim /* prosigns without already assigned values */ 138249109Sjkim 139249109Sjkim {'#', ".-..."}, /* AS */ 140249109Sjkim {'&', "...-.-"}, /* SK */ 141249109Sjkim {'*', "...-."}, /* VE */ 142249109Sjkim {'%', "-...-.-"}, /* BK */ 143249109Sjkim 144249109Sjkim {'\0', ""} 145253690Sjkim}; 146249109Sjkim 147249109Sjkim 148249109Sjkimstatic const struct morsetab iso8859_1tab[] = { 149249109Sjkim {'�', ".--.-"}, 150249109Sjkim {'�', ".--.-"}, 151253690Sjkim {'�', ".--.-"}, 152253690Sjkim {'�', ".-.-"}, 153253690Sjkim {'�', "-.-.."}, 154253690Sjkim {'�', "..-.."}, 155253690Sjkim {'�', "..-.."}, 156253690Sjkim {'�', "-..-."}, 157253690Sjkim {'�', "---."}, 158253690Sjkim {'�', "..--"}, 159249109Sjkim 160249109Sjkim {'\0', ""} 161249109Sjkim}; 162249109Sjkim 163249109Sjkimstatic const struct morsetab iso8859_7tab[] = { 164249109Sjkim /* 165249109Sjkim * The greek alphabet; you'll need an 8859-7 font in order 166249109Sjkim * to see the actual characters. 167249109Sjkim * This table does not implement: 168249109Sjkim * - the special sequences for the seven diphthongs, 169250838Sjkim * - the punctuation differences. 170249109Sjkim * Implementing these features would introduce too many 171253690Sjkim * special-cases in the program's main loop. 172250838Sjkim * The diphtong sequences are: 173253690Sjkim * alpha iota .-.- 174249109Sjkim * alpha upsilon ..-- 175249109Sjkim * epsilon upsilon ---. 176253690Sjkim * eta upsilon ...- 177253690Sjkim * omikron iota ---.. 178253690Sjkim * omikron upsilon ..- 179253690Sjkim * upsilon iota .--- 180253690Sjkim * The different punctuation symbols are: 181253690Sjkim * ; ..-.- 182253690Sjkim * ! --..-- 183253690Sjkim */ 184253690Sjkim {'�', ".-"}, /* alpha */ 185253690Sjkim {'�', ".-"}, /* alpha with acute */ 186253690Sjkim {'�', "-..."}, /* beta */ 187250838Sjkim {'�', "--."}, /* gamma */ 188250838Sjkim {'�', "-.."}, /* delta */ 189250838Sjkim {'�', "."}, /* epsilon */ 190253690Sjkim {'�', "."}, /* epsilon with acute */ 191253690Sjkim {'�', "--.."}, /* zeta */ 192250838Sjkim {'�', "...."}, /* eta */ 193250838Sjkim {'�', "...."}, /* eta with acute */ 194253690Sjkim {'�', "-.-."}, /* theta */ 195253690Sjkim {'�', ".."}, /* iota */ 196253690Sjkim {'�', ".."}, /* iota with acute */ 197249109Sjkim {'�', ".."}, /* iota with diairesis */ 198250838Sjkim {'�', ".."}, /* iota with acute and diairesis */ 199250838Sjkim {'�', "-.-"}, /* kappa */ 200250838Sjkim {'�', ".-.."}, /* lamda */ 201249109Sjkim {'�', "--"}, /* mu */ 202249109Sjkim {'�', "-."}, /* nu */ 203249109Sjkim {'�', "-..-"}, /* xi */ 204249109Sjkim {'�', "---"}, /* omicron */ 205249109Sjkim {'�', "---"}, /* omicron with acute */ 206250838Sjkim {'�', ".--."}, /* pi */ 207249109Sjkim {'�', ".-."}, /* rho */ 208250838Sjkim {'�', "..."}, /* sigma */ 209250838Sjkim {'�', "..."}, /* final sigma */ 210249109Sjkim {'�', "-"}, /* tau */ 211249109Sjkim {'�', "-.--"}, /* upsilon */ 212249109Sjkim {'�', "-.--"}, /* upsilon with acute */ 213249109Sjkim {'�', "-.--"}, /* upsilon and diairesis */ 214250838Sjkim {'�', "-.--"}, /* upsilon with acute and diairesis */ 215249109Sjkim {'�', "..-."}, /* phi */ 216253690Sjkim {'�', "----"}, /* chi */ 217253690Sjkim {'�', "--.-"}, /* psi */ 218253690Sjkim {'�', ".--"}, /* omega */ 219253690Sjkim {'�', ".--"}, /* omega with acute */ 220253690Sjkim 221253690Sjkim {'\0', ""} 222253690Sjkim}; 223253690Sjkim 224249109Sjkimstatic const struct morsetab koi8rtab[] = { 225249109Sjkim /* 226250838Sjkim * the cyrillic alphabet; you'll need a KOI8R font in order 227250838Sjkim * to see the actual characters 228249109Sjkim */ 229250838Sjkim {'�', ".-"}, /* a */ 230249109Sjkim {'�', "-..."}, /* be */ 231249109Sjkim {'�', ".--"}, /* ve */ 232249109Sjkim {'�', "--."}, /* ge */ 233249109Sjkim {'�', "-.."}, /* de */ 234249109Sjkim {'�', "."}, /* ye */ 235249109Sjkim {'�', "."}, /* yo, the same as ye */ 236249109Sjkim {'�', "...-"}, /* she */ 237249109Sjkim {'�', "--.."}, /* ze */ 238249109Sjkim {'�', ".."}, /* i */ 239249109Sjkim {'�', ".---"}, /* i kratkoye */ 240249109Sjkim {'�', "-.-"}, /* ka */ 241253690Sjkim {'�', ".-.."}, /* el */ 242250838Sjkim {'�', "--"}, /* em */ 243253690Sjkim {'�', "-."}, /* en */ 244249109Sjkim {'�', "---"}, /* o */ 245249109Sjkim {'�', ".--."}, /* pe */ 246249109Sjkim {'�', ".-."}, /* er */ 247249109Sjkim {'�', "..."}, /* es */ 248249109Sjkim {'�', "-"}, /* te */ 249249109Sjkim {'�', "..-"}, /* u */ 250249109Sjkim {'�', "..-."}, /* ef */ 251250838Sjkim {'�', "...."}, /* kha */ 252250838Sjkim {'�', "-.-."}, /* ce */ 253250838Sjkim {'�', "---."}, /* che */ 254250838Sjkim {'�', "----"}, /* sha */ 255250838Sjkim {'�', "--.-"}, /* shcha */ 256250838Sjkim {'�', "-.--"}, /* yi */ 257250838Sjkim {'�', "-..-"}, /* myakhkij znak */ 258250838Sjkim {'�', "..-.."}, /* ae */ 259250838Sjkim {'�', "..--"}, /* yu */ 260250838Sjkim {'�', ".-.-"}, /* ya */ 261250838Sjkim 262250838Sjkim {'\0', ""} 263253690Sjkim}; 264250838Sjkim 265253690Sjkimvoid show(const char *), play(const char *), morse(char); 266253690Sjkimvoid ttyout(const char *); 267250838Sjkimvoid sighandler(int); 268253690Sjkim 269253690Sjkim#define GETOPTOPTS "d:ef:lsw:" 270253690Sjkim#define USAGE \ 271253690Sjkim"usage: morse [-els] [-d device] [-w speed] [-f frequency] [string ...]\n" 272253690Sjkim 273253690Sjkimstatic int pflag, lflag, sflag, eflag; 274253690Sjkimstatic int wpm = 20; /* words per minute */ 275253690Sjkim#define FREQUENCY 600 276253690Sjkimstatic int freq = FREQUENCY; 277253690Sjkimstatic char *device; /* for tty-controlled generator */ 278250838Sjkim 279250838Sjkim#define DASH_LEN 3 280253690Sjkim#define CHAR_SPACE 3 281253690Sjkim#define WORD_SPACE (7 - CHAR_SPACE - 1) 282253690Sjkimstatic float dot_clock; 283253690Sjkimint spkr, line; 284253690Sjkimstruct termios otty, ntty; 285253690Sjkimint olflags; 286253690Sjkim 287253690Sjkim#ifdef SPEAKER 288253690Sjkimtone_t sound; 289253690Sjkim#undef GETOPTOPTS 290253690Sjkim#define GETOPTOPTS "d:ef:lpsw:" 291253690Sjkim#undef USAGE 292253690Sjkim#define USAGE \ 293253690Sjkim"usage: morse [-elps] [-d device] [-w speed] [-f frequency] [string ...]\n" 294253690Sjkim#endif 295253690Sjkim 296253690Sjkimstatic const struct morsetab *hightab; 297253690Sjkim 298253690Sjkimint 299253690Sjkimmain(int argc, char **argv) 300253690Sjkim{ 301253690Sjkim int ch, lflags; 302253690Sjkim char *p, *codeset; 303253690Sjkim 304253690Sjkim while ((ch = getopt(argc, argv, GETOPTOPTS)) != -1) 305253690Sjkim switch ((char) ch) { 306253690Sjkim case 'd': 307253690Sjkim device = optarg; 308253690Sjkim break; 309253690Sjkim case 'e': 310253690Sjkim eflag = 1; 311253690Sjkim setvbuf(stdout, 0, _IONBF, 0); 312253690Sjkim break; 313253690Sjkim case 'f': 314253690Sjkim freq = atoi(optarg); 315253690Sjkim break; 316253690Sjkim case 'l': 317253690Sjkim lflag = 1; 318253690Sjkim break; 319253690Sjkim#ifdef SPEAKER 320253690Sjkim case 'p': 321250838Sjkim pflag = 1; 322250838Sjkim break; 323249109Sjkim#endif 324249109Sjkim case 's': 325249109Sjkim sflag = 1; 326249109Sjkim break; 327249109Sjkim case 'w': 328249109Sjkim wpm = atoi(optarg); 329249109Sjkim break; 330249109Sjkim case '?': 331249109Sjkim default: 332249109Sjkim fputs(USAGE, stderr); 333249109Sjkim exit(1); 334249109Sjkim } 335249109Sjkim if (sflag && lflag) { 336249109Sjkim fputs("morse: only one of -l and -s allowed\n", stderr); 337249109Sjkim exit(1); 338249109Sjkim } 339249109Sjkim if ((pflag || device) && (sflag || lflag)) { 340253690Sjkim fputs("morse: only one of -p, -d and -l, -s allowed\n", stderr); 341249109Sjkim exit(1); 342249109Sjkim } 343249109Sjkim if ((pflag || device) && ((wpm < 1) || (wpm > 60))) { 344249109Sjkim fputs("morse: insane speed\n", stderr); 345249109Sjkim exit(1); 346249109Sjkim } 347249109Sjkim if ((pflag || device) && (freq == 0)) 348249109Sjkim freq = FREQUENCY; 349249109Sjkim 350249109Sjkim#ifdef SPEAKER 351249109Sjkim if (pflag) { 352253690Sjkim if ((spkr = open(SPEAKER, O_WRONLY, 0)) == -1) { 353249109Sjkim perror(SPEAKER); 354249109Sjkim exit(1); 355249109Sjkim } 356253690Sjkim } else 357253690Sjkim#endif 358249109Sjkim if (device) { 359249109Sjkim if ((line = open(device, O_WRONLY | O_NONBLOCK)) == -1) { 360249109Sjkim perror("open tty line"); 361249109Sjkim exit(1); 362249109Sjkim } 363249109Sjkim if (tcgetattr(line, &otty) == -1) { 364249109Sjkim perror("tcgetattr() failed"); 365249109Sjkim exit(1); 366306536Sjkim } 367249109Sjkim ntty = otty; 368249109Sjkim ntty.c_cflag |= CLOCAL; 369249109Sjkim tcsetattr(line, TCSANOW, &ntty); 370249109Sjkim lflags = fcntl(line, F_GETFL); 371249109Sjkim lflags &= ~O_NONBLOCK; 372249109Sjkim fcntl(line, F_SETFL, &lflags); 373249109Sjkim ioctl(line, TIOCMGET, &lflags); 374249109Sjkim lflags &= ~TIOCM_RTS; 375249109Sjkim olflags = lflags; 376249109Sjkim ioctl(line, TIOCMSET, &lflags); 377249109Sjkim (void)signal(SIGHUP, sighandler); 378249109Sjkim (void)signal(SIGINT, sighandler); 379249109Sjkim (void)signal(SIGQUIT, sighandler); 380249109Sjkim (void)signal(SIGTERM, sighandler); 381249109Sjkim } 382249109Sjkim if (pflag || device) { 383249109Sjkim dot_clock = wpm / 2.4; /* dots/sec */ 384253690Sjkim dot_clock = 1 / dot_clock; /* duration of a dot */ 385253690Sjkim dot_clock = dot_clock / 2; /* dot_clock runs at twice */ 386253690Sjkim /* the dot rate */ 387249109Sjkim dot_clock = dot_clock * 100; /* scale for ioctl */ 388249109Sjkim } 389249109Sjkim 390249109Sjkim argc -= optind; 391249109Sjkim argv += optind; 392249109Sjkim 393249109Sjkim if (setlocale(LC_CTYPE, "") != NULL && 394249109Sjkim *(codeset = nl_langinfo(CODESET)) != '\0') { 395249109Sjkim if (strcmp(codeset, "KOI8-R") == 0) 396249109Sjkim hightab = koi8rtab; 397249109Sjkim else if (strcmp(codeset, "ISO8859-1") == 0 || 398249109Sjkim strcmp(codeset, "ISO8859-15") == 0) 399249109Sjkim hightab = iso8859_1tab; 400249109Sjkim else if (strcmp(codeset, "ISO8859-7") == 0) 401249109Sjkim hightab = iso8859_7tab; 402249109Sjkim } 403249109Sjkim 404249109Sjkim if (lflag) 405249109Sjkim printf("m"); 406249109Sjkim if (*argv) { 407249109Sjkim do { 408249109Sjkim for (p = *argv; *p; ++p) { 409249109Sjkim if (eflag) 410249109Sjkim putchar(*p); 411249109Sjkim morse(*p); 412253690Sjkim } 413253690Sjkim if (eflag) 414253690Sjkim putchar(' '); 415253690Sjkim morse(' '); 416253690Sjkim } while (*++argv); 417253690Sjkim } else { 418249109Sjkim while ((ch = getchar()) != EOF) { 419249109Sjkim if (eflag) 420249109Sjkim putchar(ch); 421249109Sjkim morse(ch); 422249109Sjkim } 423249109Sjkim } 424250838Sjkim if (device) 425253690Sjkim tcsetattr(line, TCSANOW, &otty); 426250838Sjkim exit(0); 427250838Sjkim} 428253690Sjkim 429253690Sjkimvoid 430250838Sjkimmorse(char c) 431250838Sjkim{ 432250838Sjkim const struct morsetab *m; 433250838Sjkim 434253690Sjkim if (isalpha((unsigned char)c)) 435250838Sjkim c = tolower((unsigned char)c); 436253690Sjkim if ((c == '\r') || (c == '\n')) 437250838Sjkim c = ' '; 438250838Sjkim if (c == ' ') { 439250838Sjkim if (pflag) 440253690Sjkim play(" "); 441250838Sjkim else if (device) 442250838Sjkim ttyout(" "); 443250838Sjkim else if (lflag) 444253690Sjkim printf("\n"); 445253690Sjkim else 446250838Sjkim show(""); 447253690Sjkim return; 448253690Sjkim } 449253690Sjkim for (m = ((unsigned char)c < 0x80? mtab: hightab); 450250838Sjkim m != NULL && m->inchar != '\0'; 451253690Sjkim m++) { 452250838Sjkim if (m->inchar == c) { 453253690Sjkim if (pflag) { 454253690Sjkim play(m->morse); 455253690Sjkim } else if (device) { 456250838Sjkim ttyout(m->morse); 457250838Sjkim } else 458250838Sjkim show(m->morse); 459249109Sjkim } 460249109Sjkim } 461249109Sjkim} 462249109Sjkim 463249109Sjkimvoid 464249109Sjkimshow(const char *s) 465249109Sjkim{ 466249109Sjkim if (lflag) { 467249109Sjkim printf("%s ", s); 468249109Sjkim } else if (sflag) { 469249109Sjkim printf(" %s\n", s); 470253690Sjkim } else { 471249109Sjkim for (; *s; ++s) 472249109Sjkim printf(" %s", *s == '.' ? "dit" : "dah"); 473 printf("\n"); 474 } 475} 476 477void 478play(const char *s) 479{ 480#ifdef SPEAKER 481 const char *c; 482 483 for (c = s; *c != '\0'; c++) { 484 switch (*c) { 485 case '.': 486 sound.frequency = freq; 487 sound.duration = dot_clock; 488 break; 489 case '-': 490 sound.frequency = freq; 491 sound.duration = dot_clock * DASH_LEN; 492 break; 493 case ' ': 494 sound.frequency = 0; 495 sound.duration = dot_clock * WORD_SPACE; 496 break; 497 default: 498 sound.duration = 0; 499 } 500 if (sound.duration) { 501 if (ioctl(spkr, SPKRTONE, &sound) == -1) { 502 perror("ioctl play"); 503 exit(1); 504 } 505 } 506 sound.frequency = 0; 507 sound.duration = dot_clock; 508 if (ioctl(spkr, SPKRTONE, &sound) == -1) { 509 perror("ioctl rest"); 510 exit(1); 511 } 512 } 513 sound.frequency = 0; 514 sound.duration = dot_clock * CHAR_SPACE; 515 ioctl(spkr, SPKRTONE, &sound); 516#endif 517} 518 519void 520ttyout(const char *s) 521{ 522 const char *c; 523 int duration, on, lflags; 524 525 for (c = s; *c != '\0'; c++) { 526 switch (*c) { 527 case '.': 528 on = 1; 529 duration = dot_clock; 530 break; 531 case '-': 532 on = 1; 533 duration = dot_clock * DASH_LEN; 534 break; 535 case ' ': 536 on = 0; 537 duration = dot_clock * WORD_SPACE; 538 break; 539 default: 540 on = 0; 541 duration = 0; 542 } 543 if (on) { 544 ioctl(line, TIOCMGET, &lflags); 545 lflags |= TIOCM_RTS; 546 ioctl(line, TIOCMSET, &lflags); 547 } 548 duration *= 10000; 549 if (duration) 550 usleep(duration); 551 ioctl(line, TIOCMGET, &lflags); 552 lflags &= ~TIOCM_RTS; 553 ioctl(line, TIOCMSET, &lflags); 554 duration = dot_clock * 10000; 555 usleep(duration); 556 } 557 duration = dot_clock * CHAR_SPACE * 10000; 558 usleep(duration); 559} 560 561void 562sighandler(int signo) 563{ 564 565 ioctl(line, TIOCMSET, &olflags); 566 tcsetattr(line, TCSANOW, &otty); 567 568 signal(signo, SIG_DFL); 569 (void)kill(getpid(), signo); 570} 571