1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28/* All Rights Reserved */ 29 30/* 31 * University Copyright- Copyright (c) 1982, 1986, 1988 32 * The Regents of the University of California 33 * All Rights Reserved 34 * 35 * University Acknowledgment- Portions of this document are derived from 36 * software developed by the University of California, Berkeley, and its 37 * contributors. 38 */ 39 40#pragma ident "%Z%%M% %I% %E% SMI" 41 42#ifdef EUC 43#ifdef NROFF 44#include <stddef.h> 45#include <stdlib.h> 46#include <widec.h> 47#endif /* NROFF */ 48#endif /* EUC */ 49#include <string.h> 50#include "tdef.h" 51#include "ext.h" 52 53/* 54 * troff5.c 55 * 56 * misc processing requests 57 */ 58 59int iflist[NIF]; 60int ifx; 61 62int 63casead() 64{ 65 int i; 66 67 ad = 1; 68 /*leave admod alone*/ 69 if (skip()) 70 return (0); 71 switch (i = cbits(getch())) { 72 case 'r': /*right adj, left ragged*/ 73 admod = 2; 74 break; 75 case 'l': /*left adj, right ragged*/ 76 admod = ad = 0; /*same as casena*/ 77 break; 78 case 'c': /*centered adj*/ 79 admod = 1; 80 break; 81 case 'b': 82 case 'n': 83 admod = 0; 84 break; 85 case '0': 86 case '2': 87 case '4': 88 ad = 0; 89 case '1': 90 case '3': 91 case '5': 92 admod = (i - '0') / 2; 93 } 94 95 return (0); 96} 97 98 99int 100casena() 101{ 102 ad = 0; 103 104 return (0); 105} 106 107 108int 109casefi() 110{ 111 tbreak(); 112 fi++; 113 pendnf = 0; 114 lnsize = LNSIZE; 115 116 return (0); 117} 118 119 120int 121casenf() 122{ 123 tbreak(); 124 fi = 0; 125 126 return (0); 127} 128 129 130int 131casers() 132{ 133 dip->nls = 0; 134 135 return (0); 136} 137 138 139int 140casens() 141{ 142 dip->nls++; 143 144 return (0); 145} 146 147 148int 149chget(c) 150int c; 151{ 152 tchar i; 153 154 if (skip() || ismot(i = getch()) || cbits(i) == ' ' || cbits(i) == '\n') { 155 ch = i; 156 return(c); 157 } else 158 return(i & BYTEMASK); 159} 160 161 162int 163casecc() 164{ 165 cc = chget('.'); 166 167 return (0); 168} 169 170 171int 172casec2() 173{ 174 c2 = chget('\''); 175 176 return (0); 177} 178 179 180int 181casehc() 182{ 183 ohc = chget(OHC); 184 185 return (0); 186} 187 188 189int 190casetc() 191{ 192 tabc = chget(0); 193 194 return (0); 195} 196 197 198int 199caselc() 200{ 201 dotc = chget(0); 202 203 return (0); 204} 205 206 207int 208casehy() 209{ 210 int i; 211 212 hyf = 1; 213 if (skip()) 214 return (0); 215 noscale++; 216 i = atoi(); 217 noscale = 0; 218 if (nonumb) 219 return (0); 220 hyf = max(i, 0); 221 222 return (0); 223} 224 225 226int 227casenh() 228{ 229 hyf = 0; 230 231 return (0); 232} 233 234 235int 236max(aa, bb) 237int aa, bb; 238{ 239 if (aa > bb) 240 return(aa); 241 else 242 return(bb); 243} 244 245 246int 247casece() 248{ 249 int i; 250 251 noscale++; 252 skip(); 253 i = max(atoi(), 0); 254 if (nonumb) 255 i = 1; 256 tbreak(); 257 ce = i; 258 noscale = 0; 259 260 return (0); 261} 262 263 264int 265casein() 266{ 267 int i; 268 269 if (skip()) 270 i = in1; 271 else 272 i = max(hnumb(&in), 0); 273 tbreak(); 274 in1 = in; 275 in = i; 276 if (!nc) { 277 un = in; 278 setnel(); 279 } 280 281 return (0); 282} 283 284 285int 286casell() 287{ 288 int i; 289 290 if (skip()) 291 i = ll1; 292 else 293 i = max(hnumb(&ll), INCH / 10); 294 ll1 = ll; 295 ll = i; 296 setnel(); 297 298 return (0); 299} 300 301 302int 303caselt() 304{ 305 int i; 306 307 if (skip()) 308 i = lt1; 309 else 310 i = max(hnumb(<), 0); 311 lt1 = lt; 312 lt = i; 313 314 return (0); 315} 316 317 318int 319caseti() 320{ 321 int i; 322 323 if (skip()) 324 return (0); 325 i = max(hnumb(&in), 0); 326 tbreak(); 327 un1 = i; 328 setnel(); 329 330 return (0); 331} 332 333 334int 335casels() 336{ 337 int i; 338 339 noscale++; 340 if (skip()) 341 i = ls1; 342 else 343 i = max(inumb(&ls), 1); 344 ls1 = ls; 345 ls = i; 346 noscale = 0; 347 348 return (0); 349} 350 351 352int 353casepo() 354{ 355 int i; 356 357 if (skip()) 358 i = po1; 359 else 360 i = max(hnumb(&po), 0); 361 po1 = po; 362 po = i; 363#ifndef NROFF 364 if (!ascii) 365 esc += po - po1; 366#endif 367 return (0); 368} 369 370 371int 372casepl() 373{ 374 int i; 375 376 skip(); 377 if ((i = vnumb(&pl)) == 0) 378 pl = 11 * INCH; /*11in*/ 379 else 380 pl = i; 381 if (numtab[NL].val > pl) 382 numtab[NL].val = pl; 383 384 return (0); 385} 386 387 388int 389casewh() 390{ 391 int i, j, k; 392 393 lgf++; 394 skip(); 395 i = vnumb((int *)0); 396 if (nonumb) 397 return (0); 398 skip(); 399 j = getrq(); 400 if ((k = findn(i)) != NTRAP) { 401 mlist[k] = j; 402 return (0); 403 } 404 for (k = 0; k < NTRAP; k++) 405 if (mlist[k] == 0) 406 break; 407 if (k == NTRAP) { 408 flusho(); 409 errprint(gettext("cannot plant trap.")); 410 return (0); 411 } 412 mlist[k] = j; 413 nlist[k] = i; 414 415 return (0); 416} 417 418 419int 420casech() 421{ 422 int i, j, k; 423 424 lgf++; 425 skip(); 426 if (!(j = getrq())) 427 return (0); 428 else 429 for (k = 0; k < NTRAP; k++) 430 if (mlist[k] == j) 431 break; 432 if (k == NTRAP) 433 return (0); 434 skip(); 435 i = vnumb((int *)0); 436 if (nonumb) 437 mlist[k] = 0; 438 nlist[k] = i; 439 440 return (0); 441} 442 443 444int 445findn(i) 446int i; 447{ 448 int k; 449 450 for (k = 0; k < NTRAP; k++) 451 if ((nlist[k] == i) && (mlist[k] != 0)) 452 break; 453 return(k); 454} 455 456 457int 458casepn() 459{ 460 int i; 461 462 skip(); 463 noscale++; 464 i = max(inumb(&numtab[PN].val), 0); 465 noscale = 0; 466 if (!nonumb) { 467 npn = i; 468 npnflg++; 469 } 470 471 return (0); 472} 473 474 475int 476casebp() 477{ 478 int i; 479 struct s *savframe; 480 481 if (dip != d) 482 return (0); 483 savframe = frame; 484 skip(); 485 if ((i = inumb(&numtab[PN].val)) < 0) 486 i = 0; 487 tbreak(); 488 if (!nonumb) { 489 npn = i; 490 npnflg++; 491 } else if (dip->nls) 492 return (0); 493 eject(savframe); 494 495 return (0); 496} 497 498 499int 500casetm(ab) 501 int ab; 502{ 503 int i; 504 char tmbuf[NTM]; 505 506 lgf++; 507 copyf++; 508 if (skip() && ab) 509 errprint(gettext("User Abort")); 510 for (i = 0; i < NTM - 2; ) 511 if ((tmbuf[i++] = getch()) == '\n') 512 break; 513 if (i == NTM - 2) 514 tmbuf[i++] = '\n'; 515 tmbuf[i] = 0; 516 if (ab) /* truncate output */ 517 obufp = obuf; /* should be a function in n2.c */ 518 flusho(); 519 fdprintf(stderr, "%s", tmbuf); 520 copyf--; 521 lgf--; 522 523 return (0); 524} 525 526 527int 528casesp(a) 529int a; 530{ 531 int i, j, savlss; 532 533 tbreak(); 534 if (dip->nls || trap) 535 return (0); 536 i = findt1(); 537 if (!a) { 538 skip(); 539 j = vnumb((int *)0); 540 if (nonumb) 541 j = lss; 542 } else 543 j = a; 544 if (j == 0) 545 return (0); 546 if (i < j) 547 j = i; 548 savlss = lss; 549 if (dip != d) 550 i = dip->dnl; 551 else 552 i = numtab[NL].val; 553 if ((i + j) < 0) 554 j = -i; 555 lss = j; 556 newline(0); 557 lss = savlss; 558 559 return (0); 560} 561 562 563int 564casert() 565{ 566 int a, *p; 567 568 skip(); 569 if (dip != d) 570 p = &dip->dnl; 571 else 572 p = &numtab[NL].val; 573 a = vnumb(p); 574 if (nonumb) 575 a = dip->mkline; 576 if ((a < 0) || (a >= *p)) 577 return (0); 578 nb++; 579 casesp(a - *p); 580 581 return (0); 582} 583 584 585int 586caseem() 587{ 588 lgf++; 589 skip(); 590 em = getrq(); 591 592 return (0); 593} 594 595 596int 597casefl() 598{ 599 tbreak(); 600 flusho(); 601 602 return (0); 603} 604 605 606int 607caseev() 608{ 609 int nxev; 610 611 if (skip()) { 612e0: 613 if (evi == 0) 614 return (0); 615 nxev = evlist[--evi]; 616 goto e1; 617 } 618 noscale++; 619 nxev = atoi(); 620 noscale = 0; 621 if (nonumb) 622 goto e0; 623 flushi(); 624 if ((nxev >= NEV) || (nxev < 0) || (evi >= EVLSZ)) { 625 flusho(); 626 errprint(gettext("cannot do ev.")); 627 if (error) 628 done2(040); 629 else 630 edone(040); 631 return (0); 632 } 633 evlist[evi++] = ev; 634e1: 635 if (ev == nxev) 636 return (0); 637#ifdef INCORE 638 { 639 extern tchar corebuf[]; 640 *(struct env *)&corebuf[ev * sizeof(env)/sizeof(tchar)] = env; 641 env = *(struct env *)&corebuf[nxev * sizeof(env)/sizeof(tchar)]; 642 } 643#else 644 lseek(ibf, ev * (long)sizeof(env), 0); 645 write(ibf, (char *) & env, sizeof(env)); 646 lseek(ibf, nxev * (long)sizeof(env), 0); 647 read(ibf, (char *) & env, sizeof(env)); 648#endif 649 ev = nxev; 650 651 return (0); 652} 653 654int 655caseel() 656{ 657 if (--ifx < 0) { 658 ifx = 0; 659 iflist[0] = 0; 660 } 661 caseif(2); 662 663 return (0); 664} 665 666 667int 668caseie() 669{ 670 if (ifx >= NIF) { 671 errprint(gettext("if-else overflow.")); 672 ifx = 0; 673 edone(040); 674 } 675 caseif(1); 676 ifx++; 677 678 return (0); 679} 680 681 682int 683caseif(x) 684int x; 685{ 686 extern int falsef; 687 int notflag, true; 688 tchar i; 689 690 if (x == 2) { 691 notflag = 0; 692 true = iflist[ifx]; 693 goto i1; 694 } 695 true = 0; 696 skip(); 697 if ((cbits(i = getch())) == '!') { 698 notflag = 1; 699 } else { 700 notflag = 0; 701 ch = i; 702 } 703 i = atoi(); 704 if (!nonumb) { 705 if (i > 0) 706 true++; 707 goto i1; 708 } 709 i = getch(); 710 switch (cbits(i)) { 711 case 'e': 712 if (!(numtab[PN].val & 01)) 713 true++; 714 break; 715 case 'o': 716 if (numtab[PN].val & 01) 717 true++; 718 break; 719#ifdef NROFF 720 case 'n': 721 true++; 722 case 't': 723#endif 724#ifndef NROFF 725 case 't': 726 true++; 727 case 'n': 728#endif 729 case ' ': 730 break; 731 default: 732 true = cmpstr(i); 733 } 734i1: 735 true ^= notflag; 736 if (x == 1) 737 iflist[ifx] = !true; 738 if (true) { 739i2: 740 while ((cbits(i = getch())) == ' ') 741 ; 742 if (cbits(i) == LEFT) 743 goto i2; 744 ch = i; 745 nflush++; 746 } else { 747 copyf++; 748 falsef++; 749 eatblk(0); 750 copyf--; 751 falsef--; 752 } 753 754 return (0); 755} 756 757int 758eatblk(inblk) 759int inblk; 760{ int cnt, i; 761 762 cnt = 0; 763 do { 764 if (ch) { 765 i = cbits(ch); 766 ch = 0; 767 } else 768 i = cbits(getch0()); 769 if (i == ESC) 770 cnt++; 771 else { 772 if (cnt == 1) 773 switch (i) { 774 case '{': i = LEFT; break; 775 case '}': i = RIGHT; break; 776 case '\n': i = 'x'; break; 777 } 778 cnt = 0; 779 } 780 if (i == LEFT) eatblk(1); 781 } while ((!inblk && (i != '\n')) || (inblk && (i != RIGHT))); 782 if (i == '\n') 783 nlflg++; 784 785 return (0); 786} 787 788 789int 790cmpstr(c) 791tchar c; 792{ 793 int j, delim; 794 tchar i; 795 int val; 796 int savapts, savapts1, savfont, savfont1, savpts, savpts1; 797 tchar string[1280]; 798 tchar *sp; 799 800 if (ismot(c)) 801 return(0); 802 delim = cbits(c); 803 savapts = apts; 804 savapts1 = apts1; 805 savfont = font; 806 savfont1 = font1; 807 savpts = pts; 808 savpts1 = pts1; 809 sp = string; 810 while ((j = cbits(i = getch()))!=delim && j!='\n' && sp<&string[1280-1]) 811 *sp++ = i; 812 if (sp >= string + 1280) { 813 errprint(gettext("too-long string compare.")); 814 edone(0100); 815 } 816 if (nlflg) { 817 val = sp==string; 818 goto rtn; 819 } 820 *sp++ = 0; 821 apts = savapts; 822 apts1 = savapts1; 823 font = savfont; 824 font1 = savfont1; 825 pts = savpts; 826 pts1 = savpts1; 827 mchbits(); 828 val = 1; 829 sp = string; 830 while ((j = cbits(i = getch())) != delim && j != '\n') { 831 if (*sp != i) { 832 eat(delim); 833 val = 0; 834 goto rtn; 835 } 836 sp++; 837 } 838 if (*sp) 839 val = 0; 840rtn: 841 apts = savapts; 842 apts1 = savapts1; 843 font = savfont; 844 font1 = savfont1; 845 pts = savpts; 846 pts1 = savpts1; 847 mchbits(); 848 return(val); 849} 850 851 852int 853caserd() 854{ 855 856 lgf++; 857 skip(); 858 getname(); 859 if (!iflg) { 860 if (quiet) { 861#ifdef NROFF 862 echo_off(); 863 flusho(); 864#endif /* NROFF */ 865 fdprintf(stderr, "\007"); /*bell*/ 866 } else { 867 if (nextf[0]) { 868 fdprintf(stderr, "%s:", nextf); 869 } else { 870 fdprintf(stderr, "\007"); /*bell*/ 871 } 872 } 873 } 874 collect(); 875 tty++; 876 pushi(NBLIST*BLK, PAIR('r','d')); 877 878 return (0); 879} 880 881 882int 883rdtty() 884{ 885 char onechar; 886#ifdef EUC 887#ifdef NROFF 888 int i, n, col_index; 889#endif /* NROFF */ 890#endif /* EUC */ 891 892 onechar = 0; 893 if (read(0, &onechar, 1) == 1) { 894 if (onechar == '\n') 895 tty++; 896 else 897 tty = 1; 898#ifndef EUC 899 if (tty != 3) 900 return(onechar); 901#else 902#ifndef NROFF 903 if (tty != 3) 904 return(onechar); 905#else 906 if (tty != 3) { 907 if (!multi_locale) 908 return(onechar); 909 i = onechar & 0377; 910 *mbbuf1p++ = i; 911 *mbbuf1p = 0; 912 if ((n = mbtowc(&twc, mbbuf1, MB_CUR_MAX)) <= 0) { 913 if (mbbuf1p >= mbbuf1 + MB_CUR_MAX) { 914 i &= ~(MBMASK | CSMASK); 915 twc = 0; 916 mbbuf1p = mbbuf1; 917 *mbbuf1p = 0; 918 } else { 919 i |= (MIDDLEOFMB); 920 } 921 } else { 922 if (n > 1) 923 i |= (LASTOFMB); 924 else 925 i |= (BYTE_CHR); 926 if (isascii(twc)) { 927 col_index = 0; 928 } else { 929 if ((col_index = wcwidth(twc)) < 0) 930 col_index = 0; 931 } 932 setcsbits(i, col_index); 933 twc = 0; 934 mbbuf1p = mbbuf1; 935 } 936 return(i); 937 } 938#endif /* NROFF */ 939#endif /* EUC */ 940 } 941 popi(); 942 tty = 0; 943#ifdef NROFF 944 if (quiet) 945 echo_on(); 946#endif /* NROFF */ 947 return(0); 948} 949 950 951int 952caseec() 953{ 954 eschar = chget('\\'); 955 956 return (0); 957} 958 959 960int 961caseeo() 962{ 963 eschar = 0; 964 965 return (0); 966} 967 968 969int 970caseta() 971{ 972 int i; 973 974 tabtab[0] = nonumb = 0; 975 for (i = 0; ((i < (NTAB - 1)) && !nonumb); i++) { 976 if (skip()) 977 break; 978 tabtab[i] = max(hnumb(&tabtab[max(i-1,0)]), 0) & TABMASK; 979 if (!nonumb) 980 switch (cbits(ch)) { 981 case 'C': 982 tabtab[i] |= CTAB; 983 break; 984 case 'R': 985 tabtab[i] |= RTAB; 986 break; 987 default: /*includes L*/ 988 break; 989 } 990 nonumb = ch = 0; 991 } 992 tabtab[i] = 0; 993 994 return (0); 995} 996 997 998int 999casene() 1000{ 1001 int i, j; 1002 1003 skip(); 1004 i = vnumb((int *)0); 1005 if (nonumb) 1006 i = lss; 1007 if (i > (j = findt1())) { 1008 i = lss; 1009 lss = j; 1010 dip->nls = 0; 1011 newline(0); 1012 lss = i; 1013 } 1014 1015 return (0); 1016} 1017 1018 1019int 1020casetr() 1021{ 1022 int i, j; 1023 tchar k; 1024 1025 lgf++; 1026 skip(); 1027 while ((i = cbits(k=getch())) != '\n') { 1028 if (ismot(k)) 1029 return (0); 1030 if (ismot(k = getch())) 1031 return (0); 1032 if ((j = cbits(k)) == '\n') 1033 j = ' '; 1034 trtab[i] = j; 1035 } 1036 1037 return (0); 1038} 1039 1040 1041int 1042casecu() 1043{ 1044 cu++; 1045 caseul(); 1046 1047 return (0); 1048} 1049 1050 1051int 1052caseul() 1053{ 1054 int i; 1055 1056 noscale++; 1057 if (skip()) 1058 i = 1; 1059 else 1060 i = atoi(); 1061 if (ul && (i == 0)) { 1062 font = sfont; 1063 ul = cu = 0; 1064 } 1065 if (i) { 1066 if (!ul) { 1067 sfont = font; 1068 font = ulfont; 1069 } 1070 ul = i; 1071 } 1072 noscale = 0; 1073 mchbits(); 1074 1075 return (0); 1076} 1077 1078 1079int 1080caseuf() 1081{ 1082 int i, j; 1083 1084 if (skip() || !(i = getrq()) || i == 'S' || (j = findft(i)) == -1) 1085 ulfont = ULFONT; /*default underline position*/ 1086 else 1087 ulfont = j; 1088#ifdef NROFF 1089 if (ulfont == FT) 1090 ulfont = ULFONT; 1091#endif 1092 return (0); 1093} 1094 1095 1096int 1097caseit() 1098{ 1099 int i; 1100 1101 lgf++; 1102 it = itmac = 0; 1103 noscale++; 1104 skip(); 1105 i = atoi(); 1106 skip(); 1107 if (!nonumb && (itmac = getrq())) 1108 it = i; 1109 noscale = 0; 1110 1111 return (0); 1112} 1113 1114 1115int 1116casemc() 1117{ 1118 int i; 1119 1120 if (icf > 1) 1121 ic = 0; 1122 icf = 0; 1123 if (skip()) 1124 return (0); 1125 ic = getch(); 1126 icf = 1; 1127 skip(); 1128 i = max(hnumb((int *)0), 0); 1129 if (!nonumb) 1130 ics = i; 1131 1132 return (0); 1133} 1134 1135 1136int 1137casemk() 1138{ 1139 int i, j; 1140 1141 if (dip != d) 1142 j = dip->dnl; 1143 else 1144 j = numtab[NL].val; 1145 if (skip()) { 1146 dip->mkline = j; 1147 return (0); 1148 } 1149 if ((i = getrq()) == 0) 1150 return (0); 1151 numtab[findr(i)].val = j; 1152 1153 return (0); 1154} 1155 1156 1157int 1158casesv() 1159{ 1160 int i; 1161 1162 skip(); 1163 if ((i = vnumb((int *)0)) < 0) 1164 return (0); 1165 if (nonumb) 1166 i = 1; 1167 sv += i; 1168 caseos(); 1169 1170 return (0); 1171} 1172 1173 1174int 1175caseos() 1176{ 1177 int savlss; 1178 1179 if (sv <= findt1()) { 1180 savlss = lss; 1181 lss = sv; 1182 newline(0); 1183 lss = savlss; 1184 sv = 0; 1185 } 1186 1187 return (0); 1188} 1189 1190 1191int 1192casenm() 1193{ 1194 int i; 1195 1196 lnmod = nn = 0; 1197 if (skip()) 1198 return (0); 1199 lnmod++; 1200 noscale++; 1201 i = inumb(&numtab[LN].val); 1202 if (!nonumb) 1203 numtab[LN].val = max(i, 0); 1204 getnm(&ndf, 1); 1205 getnm(&nms, 0); 1206 getnm(&ni, 0); 1207 noscale = 0; 1208 nmbits = chbits; 1209 1210 return (0); 1211} 1212 1213 1214int 1215getnm(p, min) 1216int *p, min; 1217{ 1218 int i; 1219 1220 eat(' '); 1221 if (skip()) 1222 return (0); 1223 i = atoi(); 1224 if (nonumb) 1225 return (0); 1226 *p = max(i, min); 1227 1228 return (0); 1229} 1230 1231 1232int 1233casenn() 1234{ 1235 noscale++; 1236 skip(); 1237 nn = max(atoi(), 1); 1238 noscale = 0; 1239 1240 return (0); 1241} 1242 1243 1244int 1245caseab() 1246{ 1247 casetm(1); 1248 done3(0); 1249 1250 return (0); 1251} 1252 1253 1254#ifdef NROFF 1255/* 1256 * The following routines are concerned with setting terminal options. 1257 * The manner of doing this differs between research/Berkeley systems 1258 * and UNIX System V systems (i.e. DOCUMENTER'S WORKBENCH) 1259 * The distinction is controlled by the #define'd variable USG, 1260 * which must be set by System V users. 1261 */ 1262 1263 1264#ifdef USG 1265#include <termio.h> 1266#define ECHO_USG (ECHO | ECHOE | ECHOK | ECHONL) 1267struct termio ttys; 1268#else 1269#include <sgtty.h> 1270struct sgttyb ttys[2]; 1271#endif /* USG */ 1272 1273int ttysave[2] = {-1, -1}; 1274 1275int 1276save_tty() /*save any tty settings that may be changed*/ 1277{ 1278 1279#ifdef USG 1280 if (ioctl(0, TCGETA, &ttys) >= 0) 1281 ttysave[0] = ttys.c_lflag; 1282#else 1283 if (gtty(0, &ttys[0]) >= 0) 1284 ttysave[0] = ttys[0].sg_flags; 1285 if (gtty(1, &ttys[1]) >= 0) 1286 ttysave[1] = ttys[1].sg_flags; 1287#endif /* USG */ 1288 1289 return (0); 1290} 1291 1292 1293int 1294restore_tty() /*restore tty settings from beginning*/ 1295{ 1296 1297 if (ttysave[0] != -1) { 1298#ifdef USG 1299 ttys.c_lflag = ttysave[0]; 1300 ioctl(0, TCSETAW, &ttys); 1301#else 1302 ttys[0].sg_flags = ttysave[0]; 1303 stty(0, &ttys[0]); 1304 } 1305 if (ttysave[1] != -1) { 1306 ttys[1].sg_flags = ttysave[1]; 1307 stty(1, &ttys[1]); 1308#endif /* USG */ 1309 } 1310 1311 return (0); 1312} 1313 1314 1315int 1316set_tty() /*this replaces the use of bset and breset*/ 1317{ 1318 1319#ifndef USG /*for research/BSD only, reset CRMOD*/ 1320 if (ttysave[1] == -1) 1321 save_tty(); 1322 if (ttysave[1] != -1) { 1323 ttys[1].sg_flags &= ~CRMOD; 1324 stty(1, &ttys[1]); 1325 } 1326#endif /* USG */ 1327 1328 return (0); 1329} 1330 1331 1332int 1333echo_off() /*turn off ECHO for .rd in "-q" mode*/ 1334{ 1335 if (ttysave[0] == -1) 1336 return (0); 1337 1338#ifdef USG 1339 ttys.c_lflag &= ~ECHO_USG; 1340 ioctl(0, TCSETAW, &ttys); 1341#else 1342 ttys[0].sg_flags &= ~ECHO; 1343 stty(0, &ttys[0]); 1344#endif /* USG */ 1345 1346 return (0); 1347 1348} 1349 1350 1351int 1352echo_on() /*restore ECHO after .rd in "-q" mode*/ 1353{ 1354 if (ttysave[0] == -1) 1355 return (0); 1356 1357#ifdef USG 1358 ttys.c_lflag |= ECHO_USG; 1359 ioctl(0, TCSETAW, &ttys); 1360#else 1361 ttys[0].sg_flags |= ECHO; 1362 stty(0, &ttys[0]); 1363#endif /* USG */ 1364 1365 return (0); 1366} 1367#endif /* NROFF */ 1368