1 /* crypto/ui/ui_openssl.c -*- mode:C; c-file-style: "eay" -*- */ 2 /* Written by Richard Levitte (richard@levitte.org) and others 3 * for the OpenSSL project 2001. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 2001 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * openssl-core@openssl.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 * 57 */ 58 59 /* The lowest level part of this file was previously in crypto/des/read_pwd.c, 60 * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 61 * All rights reserved. 62 * 63 * This package is an SSL implementation written 64 * by Eric Young (eay@cryptsoft.com). 65 * The implementation was written so as to conform with Netscapes SSL. 66 * 67 * This library is free for commercial and non-commercial use as long as 68 * the following conditions are aheared to. The following conditions 69 * apply to all code found in this distribution, be it the RC4, RSA, 70 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 71 * included with this distribution is covered by the same copyright terms 72 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 73 * 74 * Copyright remains Eric Young's, and as such any Copyright notices in 75 * the code are not to be removed. 76 * If this package is used in a product, Eric Young should be given attribution 77 * as the author of the parts of the library used. 78 * This can be in the form of a textual message at program startup or 79 * in documentation (online or textual) provided with the package. 80 * 81 * Redistribution and use in source and binary forms, with or without 82 * modification, are permitted provided that the following conditions 83 * are met: 84 * 1. Redistributions of source code must retain the copyright 85 * notice, this list of conditions and the following disclaimer. 86 * 2. Redistributions in binary form must reproduce the above copyright 87 * notice, this list of conditions and the following disclaimer in the 88 * documentation and/or other materials provided with the distribution. 89 * 3. All advertising materials mentioning features or use of this software 90 * must display the following acknowledgement: 91 * "This product includes cryptographic software written by 92 * Eric Young (eay@cryptsoft.com)" 93 * The word 'cryptographic' can be left out if the rouines from the library 94 * being used are not cryptographic related :-). 95 * 4. If you include any Windows specific code (or a derivative thereof) from 96 * the apps directory (application code) you must include an acknowledgement: 97 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 98 * 99 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 100 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 101 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 102 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 103 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 104 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 105 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 106 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 107 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 108 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 109 * SUCH DAMAGE. 110 * 111 * The licence and distribution terms for any publically available version or 112 * derivative of this code cannot be changed. i.e. this code cannot simply be 113 * copied and put under another distribution licence 114 * [including the GNU Public Licence.] 115 */ 116 117 118 #include <openssl/e_os2.h> 119 120 /* need for #define _POSIX_C_SOURCE arises whenever you pass -ansi to gcc 121 * [maybe others?], because it masks interfaces not discussed in standard, 122 * sigaction and fileno included. -pedantic would be more appropriate for 123 * the intended purposes, but we can't prevent users from adding -ansi. 124 */ 125 #if defined(OPENSSL_SYSNAME_VXWORKS) 126 #include <sys/types.h> 127 #endif 128 129 #if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS) 130 #ifndef _POSIX_C_SOURCE 131 #define _POSIX_C_SOURCE 2 132 #endif 133 #endif 134 #include <signal.h> 135 #include <stdio.h> 136 #include <string.h> 137 #include <errno.h> 138 139 #if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) 140 # include <unistd.h> 141 /* If unistd.h defines _POSIX_VERSION, we conclude that we 142 * are on a POSIX system and have sigaction and termios. */ 143 # if defined(_POSIX_VERSION) 144 145 # define SIGACTION 146 # if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY) 147 # define TERMIOS 148 # endif 149 150 # endif 151 #endif 152 153 #ifdef WIN16TTY 154 # undef OPENSSL_SYS_WIN16 155 # undef WIN16 156 # undef _WINDOWS 157 # include <graph.h> 158 #endif 159 160 /* 06-Apr-92 Luke Brennan Support for VMS */ 161 #include "ui_locl.h" 162 #include "cryptlib.h" 163 164 #ifdef OPENSSL_SYS_VMS /* prototypes for sys$whatever */ 165 # include <starlet.h> 166 # ifdef __DECC 167 # pragma message disable DOLLARID 168 # endif 169 #endif 170 171 #ifdef WIN_CONSOLE_BUG 172 # include <windows.h> 173 #ifndef OPENSSL_SYS_WINCE 174 # include <wincon.h> 175 #endif 176 #endif 177 178 179 /* There are 5 types of terminal interface supported, 180 * TERMIO, TERMIOS, VMS, MSDOS and SGTTY 181 */ 182 183 #if defined(__sgi) && !defined(TERMIOS) 184 # define TERMIOS 185 # undef TERMIO 186 # undef SGTTY 187 #endif 188 189 #if defined(linux) && !defined(TERMIO) 190 # undef TERMIOS 191 # define TERMIO 192 # undef SGTTY 193 #endif 194 195 #ifdef _LIBC 196 # undef TERMIOS 197 # define TERMIO 198 # undef SGTTY 199 #endif 200 201 #if !defined(TERMIO) && !defined(TERMIOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && !defined(MAC_OS_GUSI_SOURCE) 202 # undef TERMIOS 203 # undef TERMIO 204 # define SGTTY 205 #endif 206 207 #if defined(OPENSSL_SYS_VXWORKS) 208 #undef TERMIOS 209 #undef TERMIO 210 #undef SGTTY 211 #endif 212 213 #if defined(OPENSSL_SYS_NETWARE) 214 #undef TERMIOS 215 #undef TERMIO 216 #undef SGTTY 217 #endif 218 219 #ifdef TERMIOS 220 # include <termios.h> 221 # define TTY_STRUCT struct termios 222 # define TTY_FLAGS c_lflag 223 # define TTY_get(tty,data) tcgetattr(tty,data) 224 # define TTY_set(tty,data) tcsetattr(tty,TCSANOW,data) 225 #endif 226 227 #ifdef TERMIO 228 # include <termio.h> 229 # define TTY_STRUCT struct termio 230 # define TTY_FLAGS c_lflag 231 # define TTY_get(tty,data) ioctl(tty,TCGETA,data) 232 # define TTY_set(tty,data) ioctl(tty,TCSETA,data) 233 #endif 234 235 #ifdef SGTTY 236 # include <sgtty.h> 237 # define TTY_STRUCT struct sgttyb 238 # define TTY_FLAGS sg_flags 239 # define TTY_get(tty,data) ioctl(tty,TIOCGETP,data) 240 # define TTY_set(tty,data) ioctl(tty,TIOCSETP,data) 241 #endif 242 243 #if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && !defined(OPENSSL_SYS_SUNOS) 244 # include <sys/ioctl.h> 245 #endif 246 247 #ifdef OPENSSL_SYS_MSDOS 248 # include <conio.h> 249 #endif 250 251 #ifdef OPENSSL_SYS_VMS 252 # include <ssdef.h> 253 # include <iodef.h> 254 # include <ttdef.h> 255 # include <descrip.h> 256 struct IOSB { 257 short iosb$w_value; 258 short iosb$w_count; 259 long iosb$l_info; 260 }; 261 #endif 262 263 #ifdef OPENSSL_SYS_SUNOS 264 typedef int sig_atomic_t; 265 #endif 266 267 #if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(MAC_OS_GUSI_SOURCE) || defined(OPENSSL_SYS_NETWARE) 268 /* 269 * This one needs work. As a matter of fact the code is unoperational 270 * and this is only a trick to get it compiled. 271 * <appro@fy.chalmers.se> 272 */ 273 # define TTY_STRUCT int 274 #endif 275 276 #ifndef NX509_SIG 277 # define NX509_SIG 32 278 #endif 279 280 281 /* Define globals. They are protected by a lock */ 282 #ifdef SIGACTION 283 static struct sigaction savsig[NX509_SIG]; 284 #else 285 static void (*savsig[NX509_SIG])(int ); 286 #endif 287 288 #ifdef OPENSSL_SYS_VMS 289 static struct IOSB iosb; 290 static $DESCRIPTOR(terminal,"TT"); 291 static long tty_orig[3], tty_new[3]; /* XXX Is there any guarantee that this will always suffice for the actual structures? */ 292 static long status; 293 static unsigned short channel = 0; 294 #else 295 #if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__) 296 static TTY_STRUCT tty_orig,tty_new; 297 #endif 298 #endif 299 static FILE *tty_in, *tty_out; 300 static int is_a_tty; 301 302 /* Declare static functions */ 303 #if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) 304 static int read_till_nl(FILE *); 305 static void recsig(int); 306 static void pushsig(void); 307 static void popsig(void); 308 #endif 309 #if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) 310 static int noecho_fgets(char *buf, int size, FILE *tty); 311 #endif 312 static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl); 313 314 static int read_string(UI *ui, UI_STRING *uis); 315 static int write_string(UI *ui, UI_STRING *uis); 316 317 static int open_console(UI *ui); 318 static int echo_console(UI *ui); 319 static int noecho_console(UI *ui); 320 static int close_console(UI *ui); 321 322 static UI_METHOD ui_openssl = 323 { 324 "OpenSSL default user interface", 325 open_console, 326 write_string, 327 NULL, /* No flusher is needed for command lines */ 328 read_string, 329 close_console, 330 NULL 331 }; 332 333 /* The method with all the built-in thingies */ 334 UI_METHOD *UI_OpenSSL(void) 335 { 336 return &ui_openssl; 337 } 338 339 /* The following function makes sure that info and error strings are printed 340 before any prompt. */ 341 static int write_string(UI *ui, UI_STRING *uis) 342 { 343 switch (UI_get_string_type(uis)) 344 { 345 case UIT_ERROR: 346 case UIT_INFO: 347 fputs(UI_get0_output_string(uis), tty_out); 348 fflush(tty_out); 349 break; 350 default: 351 break; 352 } 353 return 1; 354 } 355 356 static int read_string(UI *ui, UI_STRING *uis) 357 { 358 int ok = 0; 359 360 switch (UI_get_string_type(uis)) 361 { 362 case UIT_BOOLEAN: 363 fputs(UI_get0_output_string(uis), tty_out); 364 fputs(UI_get0_action_string(uis), tty_out); 365 fflush(tty_out); 366 return read_string_inner(ui, uis, 367 UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 0); 368 case UIT_PROMPT: 369 fputs(UI_get0_output_string(uis), tty_out); 370 fflush(tty_out); 371 return read_string_inner(ui, uis, 372 UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 1); 373 case UIT_VERIFY: 374 fprintf(tty_out,"Verifying - %s", 375 UI_get0_output_string(uis)); 376 fflush(tty_out); 377 if ((ok = read_string_inner(ui, uis, 378 UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 1)) <= 0) 379 return ok; 380 if (strcmp(UI_get0_result_string(uis), 381 UI_get0_test_string(uis)) != 0) 382 { 383 fprintf(tty_out,"Verify failure\n"); 384 fflush(tty_out); 385 return 0; 386 } 387 break; 388 default: 389 break; 390 } 391 return 1; 392 } 393 394 395 #if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) 396 /* Internal functions to read a string without echoing */ 397 static int read_till_nl(FILE *in) 398 { 399 #define SIZE 4 400 char buf[SIZE+1]; 401 402 do { 403 if (!fgets(buf,SIZE,in)) 404 return 0; 405 } while (strchr(buf,'\n') == NULL); 406 return 1; 407 } 408 409 static volatile sig_atomic_t intr_signal; 410 #endif 411 412 static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl) 413 { 414 static int ps; 415 int ok; 416 char result[BUFSIZ]; 417 int maxsize = BUFSIZ-1; 418 #if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) 419 char *p; 420 421 intr_signal=0; 422 ok=0; 423 ps=0; 424 425 pushsig(); 426 ps=1; 427 428 if (!echo && !noecho_console(ui)) 429 goto error; 430 ps=2; 431 432 result[0]='\0'; 433 #ifdef OPENSSL_SYS_MSDOS 434 if (!echo) 435 { 436 noecho_fgets(result,maxsize,tty_in); 437 p=result; /* FIXME: noecho_fgets doesn't return errors */ 438 } 439 else 440 p=fgets(result,maxsize,tty_in); 441 #else 442 p=fgets(result,maxsize,tty_in); 443 #endif 444 if(!p) 445 goto error; 446 if (feof(tty_in)) goto error; 447 if (ferror(tty_in)) goto error; 448 if ((p=(char *)strchr(result,'\n')) != NULL) 449 { 450 if (strip_nl) 451 *p='\0'; 452 } 453 else 454 if (!read_till_nl(tty_in)) 455 goto error; 456 if (UI_set_result(ui, uis, result) >= 0) 457 ok=1; 458 459 error: 460 if (intr_signal == SIGINT) 461 ok=-1; 462 if (!echo) fprintf(tty_out,"\n"); 463 if (ps >= 2 && !echo && !echo_console(ui)) 464 ok=0; 465 466 if (ps >= 1) 467 popsig(); 468 #else 469 ok=1; 470 #endif 471 472 OPENSSL_cleanse(result,BUFSIZ); 473 return ok; 474 } 475 476 477 /* Internal functions to open, handle and close a channel to the console. */ 478 static int open_console(UI *ui) 479 { 480 CRYPTO_w_lock(CRYPTO_LOCK_UI); 481 is_a_tty = 1; 482 483 #if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS) 484 tty_in=stdin; 485 tty_out=stderr; 486 #else 487 # ifdef OPENSSL_SYS_MSDOS 488 # define DEV_TTY "con" 489 # else 490 # define DEV_TTY "/dev/tty" 491 # endif 492 if ((tty_in=fopen(DEV_TTY,"r")) == NULL) 493 tty_in=stdin; 494 if ((tty_out=fopen(DEV_TTY,"w")) == NULL) 495 tty_out=stderr; 496 #endif 497 498 #if defined(TTY_get) && !defined(OPENSSL_SYS_VMS) 499 if (TTY_get(fileno(tty_in),&tty_orig) == -1) 500 { 501 #ifdef ENOTTY 502 if (errno == ENOTTY) 503 is_a_tty=0; 504 else 505 #endif 506 #ifdef EINVAL 507 /* Ariel Glenn ariel@columbia.edu reports that solaris 508 * can return EINVAL instead. This should be ok */ 509 if (errno == EINVAL) 510 is_a_tty=0; 511 else 512 #endif 513 return 0; 514 } 515 #endif 516 #ifdef OPENSSL_SYS_VMS 517 status = sys$assign(&terminal,&channel,0,0); 518 if (status != SS$_NORMAL) 519 return 0; 520 status=sys$qiow(0,channel,IO$_SENSEMODE,&iosb,0,0,tty_orig,12,0,0,0,0); 521 if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) 522 return 0; 523 #endif 524 return 1; 525 } 526 527 static int noecho_console(UI *ui) 528 { 529 #ifdef TTY_FLAGS 530 memcpy(&(tty_new),&(tty_orig),sizeof(tty_orig)); 531 tty_new.TTY_FLAGS &= ~ECHO; 532 #endif 533 534 #if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) 535 if (is_a_tty && (TTY_set(fileno(tty_in),&tty_new) == -1)) 536 return 0; 537 #endif 538 #ifdef OPENSSL_SYS_VMS 539 tty_new[0] = tty_orig[0]; 540 tty_new[1] = tty_orig[1] | TT$M_NOECHO; 541 tty_new[2] = tty_orig[2]; 542 status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0); 543 if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) 544 return 0; 545 #endif 546 return 1; 547 } 548 549 static int echo_console(UI *ui) 550 { 551 #if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) 552 memcpy(&(tty_new),&(tty_orig),sizeof(tty_orig)); 553 tty_new.TTY_FLAGS |= ECHO; 554 #endif 555 556 #if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) 557 if (is_a_tty && (TTY_set(fileno(tty_in),&tty_new) == -1)) 558 return 0; 559 #endif 560 #ifdef OPENSSL_SYS_VMS 561 tty_new[0] = tty_orig[0]; 562 tty_new[1] = tty_orig[1] & ~TT$M_NOECHO; 563 tty_new[2] = tty_orig[2]; 564 status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0); 565 if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) 566 return 0; 567 #endif 568 return 1; 569 } 570 571 static int close_console(UI *ui) 572 { 573 if (tty_in != stdin) fclose(tty_in); 574 if (tty_out != stderr) fclose(tty_out); 575 #ifdef OPENSSL_SYS_VMS 576 status = sys$dassgn(channel); 577 #endif 578 CRYPTO_w_unlock(CRYPTO_LOCK_UI); 579 580 return 1; 581 } 582 583 584 #if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) 585 /* Internal functions to handle signals and act on them */ 586 static void pushsig(void) 587 { 588 #ifndef OPENSSL_SYS_WIN32 589 int i; 590 #endif 591 #ifdef SIGACTION 592 struct sigaction sa; 593 594 memset(&sa,0,sizeof sa); 595 sa.sa_handler=recsig; 596 #endif 597 598 #ifdef OPENSSL_SYS_WIN32 599 savsig[SIGABRT]=signal(SIGABRT,recsig); 600 savsig[SIGFPE]=signal(SIGFPE,recsig); 601 savsig[SIGILL]=signal(SIGILL,recsig); 602 savsig[SIGINT]=signal(SIGINT,recsig); 603 savsig[SIGSEGV]=signal(SIGSEGV,recsig); 604 savsig[SIGTERM]=signal(SIGTERM,recsig); 605 #else 606 for (i=1; i<NX509_SIG; i++) 607 { 608 #ifdef SIGUSR1 609 if (i == SIGUSR1) 610 continue; 611 #endif 612 #ifdef SIGUSR2 613 if (i == SIGUSR2) 614 continue; 615 #endif 616 #ifdef SIGKILL 617 if (i == SIGKILL) /* We can't make any action on that. */ 618 continue; 619 #endif 620 #ifdef SIGACTION 621 sigaction(i,&sa,&savsig[i]); 622 #else 623 savsig[i]=signal(i,recsig); 624 #endif 625 } 626 #endif 627 628 #ifdef SIGWINCH 629 signal(SIGWINCH,SIG_DFL); 630 #endif 631 } 632 633 static void popsig(void) 634 { 635 #ifdef OPENSSL_SYS_WIN32 636 signal(SIGABRT,savsig[SIGABRT]); 637 signal(SIGFPE,savsig[SIGFPE]); 638 signal(SIGILL,savsig[SIGILL]); 639 signal(SIGINT,savsig[SIGINT]); 640 signal(SIGSEGV,savsig[SIGSEGV]); 641 signal(SIGTERM,savsig[SIGTERM]); 642 #else 643 int i; 644 for (i=1; i<NX509_SIG; i++) 645 { 646 #ifdef SIGUSR1 647 if (i == SIGUSR1) 648 continue; 649 #endif 650 #ifdef SIGUSR2 651 if (i == SIGUSR2) 652 continue; 653 #endif 654 #ifdef SIGACTION 655 sigaction(i,&savsig[i],NULL); 656 #else 657 signal(i,savsig[i]); 658 #endif 659 } 660 #endif 661 } 662 663 static void recsig(int i) 664 { 665 intr_signal=i; 666 } 667 #endif 668 669 /* Internal functions specific for Windows */ 670 #if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) 671 static int noecho_fgets(char *buf, int size, FILE *tty) 672 { 673 int i; 674 char *p; 675 676 p=buf; 677 for (;;) 678 { 679 if (size == 0) 680 { 681 *p='\0'; 682 break; 683 } 684 size--; 685 #ifdef WIN16TTY 686 i=_inchar(); 687 #elif defined(_WIN32) 688 i=_getch(); 689 #else 690 i=getch(); 691 #endif 692 if (i == '\r') i='\n'; 693 *(p++)=i; 694 if (i == '\n') 695 { 696 *p='\0'; 697 break; 698 } 699 } 700 #ifdef WIN_CONSOLE_BUG 701 /* Win95 has several evil console bugs: one of these is that the 702 * last character read using getch() is passed to the next read: this is 703 * usually a CR so this can be trouble. No STDIO fix seems to work but 704 * flushing the console appears to do the trick. 705 */ 706 { 707 HANDLE inh; 708 inh = GetStdHandle(STD_INPUT_HANDLE); 709 FlushConsoleInputBuffer(inh); 710 } 711 #endif 712 return(strlen(buf)); 713 } 714 #endif 715