morse.c (54622) | morse.c (57527) |
---|---|
1/* 2 * Copyright (c) 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 33 unchanged lines hidden (view full) --- 42 The Regents of the University of California. All rights reserved.\n"; 43#endif /* not lint */ 44 45#ifndef lint 46#if 0 47static char sccsid[] = "@(#)morse.c 8.1 (Berkeley) 5/31/93"; 48#endif 49static const char rcsid[] = | 1/* 2 * Copyright (c) 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 33 unchanged lines hidden (view full) --- 42 The Regents of the University of California. All rights reserved.\n"; 43#endif /* not lint */ 44 45#ifndef lint 46#if 0 47static char sccsid[] = "@(#)morse.c 8.1 (Berkeley) 5/31/93"; 48#endif 49static const char rcsid[] = |
50 "$FreeBSD: head/games/morse/morse.c 54622 1999-12-15 04:28:10Z billf $"; | 50 "$FreeBSD: head/games/morse/morse.c 57527 2000-02-27 01:21:28Z joerg $"; |
51#endif /* not lint */ 52 | 51#endif /* not lint */ 52 |
53#include <stdio.h> | 53#include <sys/time.h> 54 |
54#include <ctype.h> | 55#include <ctype.h> |
56#include <fcntl.h> |
|
55#include <locale.h> | 57#include <locale.h> |
58#include <signal.h> 59#include <stdio.h> |
|
56#include <stdlib.h> 57#include <string.h> | 60#include <stdlib.h> 61#include <string.h> |
62#include <termios.h> |
|
58#include <unistd.h> 59 60#ifdef SPEAKER 61#include <machine/speaker.h> | 63#include <unistd.h> 64 65#ifdef SPEAKER 66#include <machine/speaker.h> |
62#include <fcntl.h> | |
63#endif 64 65struct morsetab { 66 char inchar; 67 char *morse; 68}; 69 70static const struct morsetab mtab[] = { --- 118 unchanged lines hidden (view full) --- 189 {'�', "..-.."}, /* ae */ 190 {'�', "..--"}, /* yu */ 191 {'�', ".-.-"}, /* ya */ 192 193 {'\0', ""} 194}; 195 196void show(const char *), play(const char *), morse(char); | 67#endif 68 69struct morsetab { 70 char inchar; 71 char *morse; 72}; 73 74static const struct morsetab mtab[] = { --- 118 unchanged lines hidden (view full) --- 193 {'�', "..-.."}, /* ae */ 194 {'�', "..--"}, /* yu */ 195 {'�', ".-.-"}, /* ya */ 196 197 {'\0', ""} 198}; 199 200void show(const char *), play(const char *), morse(char); |
201void ttyout(const char *); 202void sighandler(int); |
|
197 | 203 |
198static int pflag, sflag; | 204#define GETOPTOPTS "d:ef:sw:" 205#define USAGE \ 206"usage: morse [-s] [-e] [-d device] [-w speed] [-f frequency] [string ...]\n" 207 208static int pflag, sflag, eflag; |
199static int wpm = 20; /* words per minute */ 200#define FREQUENCY 600 201static int freq = FREQUENCY; | 209static int wpm = 20; /* words per minute */ 210#define FREQUENCY 600 211static int freq = FREQUENCY; |
212static char *device; /* for tty-controlled generator */ |
|
202 | 213 |
203#ifdef SPEAKER | |
204#define DASH_LEN 3 205#define CHAR_SPACE 3 206#define WORD_SPACE (7 - CHAR_SPACE - 1) 207static float dot_clock; | 214#define DASH_LEN 3 215#define CHAR_SPACE 3 216#define WORD_SPACE (7 - CHAR_SPACE - 1) 217static float dot_clock; |
208int spkr; | 218int spkr, line; 219struct termios otty, ntty; 220int olflags; 221 222#ifdef SPEAKER |
209tone_t sound; | 223tone_t sound; |
224#undef GETOPTOPTS 225#define GETOPTOPTS "d:ef:psw:" 226#undef USAGE 227#define USAGE \ 228"usage: morse [-s] [-p] [-e] [-d device] [-w speed] [-f frequency] [string ...]\n" |
|
210#endif 211 212static const struct morsetab *hightab = iso8859tab; 213 214int 215main(int argc, char **argv) 216{ | 229#endif 230 231static const struct morsetab *hightab = iso8859tab; 232 233int 234main(int argc, char **argv) 235{ |
217 int ch; | 236 int ch, lflags; |
218 char *p; 219 | 237 char *p; 238 |
220 while ((ch = getopt(argc, argv, "spw:f:")) != -1) | 239 while ((ch = getopt(argc, argv, GETOPTOPTS)) != -1) |
221 switch ((char) ch) { | 240 switch ((char) ch) { |
241 case 'd': 242 device = optarg; 243 break; 244 case 'e': 245 eflag = 1; 246 setvbuf(stdout, 0, _IONBF, 0); 247 break; |
|
222 case 'f': 223 freq = atoi(optarg); 224 break; | 248 case 'f': 249 freq = atoi(optarg); 250 break; |
251#ifdef SPEAKER |
|
225 case 'p': 226 pflag = 1; 227 break; | 252 case 'p': 253 pflag = 1; 254 break; |
255#endif |
|
228 case 's': 229 sflag = 1; 230 break; 231 case 'w': 232 wpm = atoi(optarg); 233 break; 234 case '?': 235 default: | 256 case 's': 257 sflag = 1; 258 break; 259 case 'w': 260 wpm = atoi(optarg); 261 break; 262 case '?': 263 default: |
236 fputs("usage: morse [-s] [-p] [-w speed] [-f frequency] [string ...]\n", stderr); | 264 fputs(USAGE, stderr); |
237 exit(1); 238 } | 265 exit(1); 266 } |
239 if (pflag && sflag) { 240 fputs("morse: only one of -p and -s allowed\n", stderr); | 267 if ((pflag || device) && sflag) { 268 fputs("morse: only one of -p, -d and -s allowed\n", stderr); |
241 exit(1); 242 } | 269 exit(1); 270 } |
243 if (pflag && ((wpm < 1) || (wpm > 60))) { | 271 if ((pflag || device) && ((wpm < 1) || (wpm > 60))) { |
244 fputs("morse: insane speed\n", stderr); 245 exit(1); 246 } | 272 fputs("morse: insane speed\n", stderr); 273 exit(1); 274 } |
247 if (pflag && (freq == 0)) | 275 if ((pflag || device) && (freq == 0)) |
248 freq = FREQUENCY; 249 250#ifdef SPEAKER 251 if (pflag) { 252 if ((spkr = open(SPEAKER, O_WRONLY, 0)) == -1) { 253 perror(SPEAKER); 254 exit(1); 255 } | 276 freq = FREQUENCY; 277 278#ifdef SPEAKER 279 if (pflag) { 280 if ((spkr = open(SPEAKER, O_WRONLY, 0)) == -1) { 281 perror(SPEAKER); 282 exit(1); 283 } |
284 } else 285#endif 286 if (device) { 287 if ((line = open(device, O_WRONLY | O_NONBLOCK)) == -1) { 288 perror("open tty line"); 289 exit(1); 290 } 291 if (tcgetattr(line, &otty) == -1) { 292 perror("tcgetattr() failed"); 293 exit(1); 294 } 295 ntty = otty; 296 ntty.c_cflag |= CLOCAL; 297 tcsetattr(line, TCSANOW, &ntty); 298 lflags = fcntl(line, F_GETFL); 299 lflags &= ~O_NONBLOCK; 300 fcntl(line, F_SETFL, &lflags); 301 ioctl(line, TIOCMGET, &lflags); 302 lflags &= ~TIOCM_RTS; 303 olflags = lflags; 304 ioctl(line, TIOCMSET, &lflags); 305 (void)signal(SIGHUP, sighandler); 306 (void)signal(SIGINT, sighandler); 307 (void)signal(SIGQUIT, sighandler); 308 (void)signal(SIGTERM, sighandler); 309 } 310 if (pflag || device) { |
|
256 dot_clock = wpm / 2.4; /* dots/sec */ 257 dot_clock = 1 / dot_clock; /* duration of a dot */ 258 dot_clock = dot_clock / 2; /* dot_clock runs at twice */ 259 /* the dot rate */ 260 dot_clock = dot_clock * 100; /* scale for ioctl */ 261 } | 311 dot_clock = wpm / 2.4; /* dots/sec */ 312 dot_clock = 1 / dot_clock; /* duration of a dot */ 313 dot_clock = dot_clock / 2; /* dot_clock runs at twice */ 314 /* the dot rate */ 315 dot_clock = dot_clock * 100; /* scale for ioctl */ 316 } |
262#endif | 317 |
263 argc -= optind; 264 argv += optind; 265 266 if((p = getenv("LC_CTYPE")) || 267 (p = getenv("LC_ALL")) || 268 (p = getenv("LANG"))) { 269 if(strlen(p) >= sizeof(".KOI8-R") && 270 strcasecmp(&p[strlen(p) + 1 - sizeof(".KOI8-R")], ".KOI8-R") == 0) 271 hightab = koi8rtab; 272 } 273 (void) setlocale(LC_CTYPE, ""); 274 275 if (*argv) { 276 do { 277 for (p = *argv; *p; ++p) { | 318 argc -= optind; 319 argv += optind; 320 321 if((p = getenv("LC_CTYPE")) || 322 (p = getenv("LC_ALL")) || 323 (p = getenv("LANG"))) { 324 if(strlen(p) >= sizeof(".KOI8-R") && 325 strcasecmp(&p[strlen(p) + 1 - sizeof(".KOI8-R")], ".KOI8-R") == 0) 326 hightab = koi8rtab; 327 } 328 (void) setlocale(LC_CTYPE, ""); 329 330 if (*argv) { 331 do { 332 for (p = *argv; *p; ++p) { |
333 if (eflag) 334 putchar(*p); |
|
278 morse(*p); 279 } | 335 morse(*p); 336 } |
337 if (eflag) 338 putchar(' '); |
|
280 morse(' '); 281 } while (*++argv); 282 } else { | 339 morse(' '); 340 } while (*++argv); 341 } else { |
283 while ((ch = getchar()) != EOF) | 342 while ((ch = getchar()) != EOF) { 343 if (eflag) 344 putchar(ch); |
284 morse(ch); | 345 morse(ch); |
346 } |
|
285 } | 347 } |
348 if (device) 349 tcsetattr(line, TCSANOW, &otty); |
|
286 exit(0); 287} 288 289void 290morse(char c) 291{ 292 const struct morsetab *m; 293 294 if (isalpha((unsigned char)c)) 295 c = tolower((unsigned char)c); 296 if ((c == '\r') || (c == '\n')) 297 c = ' '; 298 if (c == ' ') { 299 if (pflag) { 300 play(" "); 301 return; | 350 exit(0); 351} 352 353void 354morse(char c) 355{ 356 const struct morsetab *m; 357 358 if (isalpha((unsigned char)c)) 359 c = tolower((unsigned char)c); 360 if ((c == '\r') || (c == '\n')) 361 c = ' '; 362 if (c == ' ') { 363 if (pflag) { 364 play(" "); 365 return; |
366 } else if (device) { 367 ttyout(" "); 368 return; |
|
302 } else { 303 show(""); 304 return; 305 } 306 } 307 for (m = ((unsigned char)c < 0x80? mtab: hightab); 308 m->inchar != '\0'; 309 m++) { 310 if (m->inchar == c) { 311 if (pflag) { 312 play(m->morse); | 369 } else { 370 show(""); 371 return; 372 } 373 } 374 for (m = ((unsigned char)c < 0x80? mtab: hightab); 375 m->inchar != '\0'; 376 m++) { 377 if (m->inchar == c) { 378 if (pflag) { 379 play(m->morse); |
380 } else if (device) { 381 ttyout(m->morse); |
|
313 } else 314 show(m->morse); 315 } 316 } 317} 318 319void 320show(const char *s) --- 42 unchanged lines hidden (view full) --- 363 exit(1); 364 } 365 } 366 sound.frequency = 0; 367 sound.duration = dot_clock * CHAR_SPACE; 368 ioctl(spkr, SPKRTONE, &sound); 369#endif 370} | 382 } else 383 show(m->morse); 384 } 385 } 386} 387 388void 389show(const char *s) --- 42 unchanged lines hidden (view full) --- 432 exit(1); 433 } 434 } 435 sound.frequency = 0; 436 sound.duration = dot_clock * CHAR_SPACE; 437 ioctl(spkr, SPKRTONE, &sound); 438#endif 439} |
440 441void 442ttyout(const char *s) 443{ 444 const char *c; 445 int duration, on, lflags; 446 447 for (c = s; *c != '\0'; c++) { 448 switch (*c) { 449 case '.': 450 on = 1; 451 duration = dot_clock; 452 break; 453 case '-': 454 on = 1; 455 duration = dot_clock * DASH_LEN; 456 break; 457 case ' ': 458 on = 0; 459 duration = dot_clock * WORD_SPACE; 460 break; 461 default: 462 on = 0; 463 duration = 0; 464 } 465 if (on) { 466 ioctl(line, TIOCMGET, &lflags); 467 lflags |= TIOCM_RTS; 468 ioctl(line, TIOCMSET, &lflags); 469 } 470 duration *= 10000; 471 if (duration) 472 usleep(duration); 473 ioctl(line, TIOCMGET, &lflags); 474 lflags &= ~TIOCM_RTS; 475 ioctl(line, TIOCMSET, &lflags); 476 duration = dot_clock * 10000; 477 usleep(duration); 478 } 479 duration = dot_clock * CHAR_SPACE * 10000; 480 usleep(duration); 481} 482 483void 484sighandler(int signo) 485{ 486 487 ioctl(line, TIOCMSET, &olflags); 488 tcsetattr(line, TCSANOW, &otty); 489 490 signal(signo, SIG_DFL); 491 (void)kill(getpid(), signo); 492} |
|