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 2001 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1988 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 #include <stdlib.h> 43 #include <string.h> 44 #include <sys/types.h> 45 #include "curses_inc.h" 46 #include "print.h" 47 #include <signal.h> /* use this file to determine if this is SVR4.0 system */ 48 49 #ifdef SIGSTOP /* SVR4.0 and beyond */ 50 #define _ULIBTI "/usr/share/lib/terminfo" 51 #else 52 #define _ULIBTI "/usr/lib/terminfo" 53 #endif 54 55 char *progname; 56 57 /* global variables */ 58 static enum printtypes printing = pr_none; 59 static int onecolumn = 0; /* print a single column */ 60 static int width = 60; /* width of multi-column printing */ 61 static int restrictterm = 1; /* restrict termcap names */ 62 63 /* local variables */ 64 static int printed = 0; 65 static size_t caplen = 0; 66 67 void 68 pr_init(enum printtypes type) 69 { 70 printing = type; 71 } 72 73 void 74 pr_onecolumn(int onoff) 75 { 76 onecolumn = onoff; 77 } 78 79 void 80 pr_width(int nwidth) 81 { 82 if (nwidth > 0) 83 width = nwidth; 84 } 85 86 void 87 pr_caprestrict(int onoff) 88 { 89 restrictterm = onoff; 90 } 91 92 static char capbools[] = 93 "ambsbwdadbeoeshchshzinkmmimsncnsosptulxbxnxoxsxt"; 94 static int ncapbools = sizeof (capbools) / sizeof (capbools[0]); 95 96 static char capnums[] = 97 "codBdCdFdNdTknlipbsgug"; 98 static int ncapnums = sizeof (capnums) / sizeof (capnums[0]); 99 100 static char capstrs[] = 101 "ALDCDLDOICLERISFSRUPaealasbcbtcdcechclcmcsctcvdcdldmdsedeifshoi1i2i" 102 "cifimipisk0k1k2k3k4k5k6k7k8k9kbkdkekhklkokrkskul0l1l2l3l4l5l6l7l" 103 "8l9ndnlpcr1r2r3rcrfrpscsesosrsttetitsucueupusvbvevivs"; 104 static int ncapstrs = sizeof (capstrs) / sizeof (capstrs[0]); 105 106 static int 107 findcapname(char *capname, char *caplist, int listsize) 108 { 109 int low = 0, mid, high = listsize - 2; 110 while (low <= high) { 111 mid = (low + high) / 4 * 2; 112 if (capname[0] == caplist[mid]) { 113 if (capname[1] == caplist[mid + 1]) 114 return (1); 115 else if (capname[1] < caplist[mid + 1]) 116 high = mid - 2; 117 else 118 low = mid + 2; 119 } else if (capname[0] < caplist[mid]) 120 high = mid - 2; 121 else 122 low = mid + 2; 123 } 124 return (0); 125 /* 126 * for (; *caplist; caplist += 2) 127 * if (caplist[0] == capname[0] && caplist[1] == capname[1]) 128 * return (1); 129 * return (0); 130 */ 131 } 132 133 /* 134 * Print out the first line of an entry. 135 */ 136 void 137 pr_heading(char *term, char *synonyms) 138 { 139 int do_print = 0; /* Can we print the path of the file ? */ 140 char buffer[512]; /* Holds search pathname */ 141 FILE *work_fp; /* Used to try and open the files */ 142 char tail[4]; /* Used for terminfo pathname suffix */ 143 char *terminfo; /* The value of $TERMINFO */ 144 145 146 /* 147 * Try to obtain $TERMINFO 148 */ 149 terminfo = getenv("TERMINFO"); 150 151 if (term == (char *)0) 152 term = ""; 153 /* 154 * Build the suffix for this device 155 */ 156 tail[0] = '/'; 157 tail[1] = *term; 158 tail[2] = '/'; 159 tail[3] = '\0'; 160 161 /* 162 * If we have it - use it, otherwise use /usr/share/lib/terminfo 163 * as base directory 164 */ 165 if (terminfo != NULL) 166 (void) sprintf(buffer, "%s%s%s", terminfo, tail, term); 167 else 168 (void) sprintf(buffer, "%s%s%s", _ULIBTI, tail, term); 169 170 /* 171 * Attempt to open the file. 172 */ 173 if ((work_fp = fopen(buffer, "r")) == NULL) { 174 /* 175 * Open failed. If we were looking in /usr/share/lib/terminfo 176 * we are done, otherwise look there next. 177 */ 178 if (strncmp(buffer, _ULIBTI, strlen(_ULIBTI)) == 0) { 179 /* 180 * We are done. Not in /usr/share/lib/terminfo, 181 * and $TERMINFO is not set. 182 */ 183 (void) fprintf(stderr, "Error: Term \"%s\" not " 184 "found in %s\n", term, _ULIBTI); 185 } else { 186 /* 187 * Check /usr/share/lib/terminfo last. If this fails, 188 * all hope is lost as we know it is not in $TERMINFO. 189 */ 190 (void) sprintf(buffer, "%s%s%s", _ULIBTI, tail, term); 191 192 if ((work_fp = fopen(buffer, "r")) == NULL) { 193 /* 194 * All hope is lost 195 */ 196 (void) fprintf(stderr, "Error: Term \"%s\" not " 197 "found in %s or %s\n", term, _ULIBTI, 198 getenv("TERMINFO")); 199 } else do_print = 1; 200 } 201 } else do_print = 1; 202 203 /* 204 * If we found it - print the comment(after closing the file) 205 */ 206 if (do_print && *term) { 207 (void) fclose(work_fp); 208 (void) printf("# Reconstructed via infocmp from file: " 209 "%s\n", buffer); 210 } 211 212 switch ((int)printing) { 213 case (int)pr_terminfo: 214 (void) printf("%s,\n", synonyms); 215 break; 216 case (int)pr_cap: 217 (void) printf("%s:\\\n", synonyms); 218 caplen = strlen(synonyms) + 1; 219 break; 220 case (int)pr_longnames: 221 (void) printf("Terminal type %s\n", term); 222 (void) printf(" %s\n", synonyms); 223 break; 224 } 225 } 226 227 void 228 pr_bheading(void) 229 { 230 if (printing == pr_longnames) 231 (void) printf("flags\n"); 232 printed = 0; 233 } 234 235 void 236 pr_boolean(char *infoname, char *capname, char *fullname, int value) 237 { 238 int vlen; 239 size_t nlen; 240 241 if (printing == pr_cap && restrictterm && 242 !findcapname(capname, capbools, ncapbools)) 243 return; 244 245 if (onecolumn) { 246 if (value < 0) 247 switch ((int)printing) { 248 case (int)pr_terminfo: 249 (void) printf("\t%s@,\n", infoname); 250 break; 251 case (int)pr_cap: 252 (void) printf("\t:%s@:\\\n", capname); 253 caplen += 4 + strlen(capname); 254 break; 255 case (int)pr_longnames: 256 (void) printf(" %s@\n", fullname); 257 } 258 else 259 switch ((int)printing) { 260 case (int)pr_terminfo: 261 (void) printf("\t%s,\n", infoname); 262 break; 263 case (int)pr_cap: 264 (void) printf("\t:%s:\\\n", capname); 265 caplen += 3 + strlen(capname); 266 break; 267 case (int)pr_longnames: 268 (void) printf(" %s\n", fullname); 269 } 270 } else { 271 switch ((int)printing) { 272 case (int)pr_terminfo: nlen = strlen(infoname); 273 break; 274 case (int)pr_cap: nlen = strlen(capname); 275 break; 276 case (int)pr_longnames: 277 nlen = strlen(fullname); 278 break; 279 } 280 vlen = (value < 0) ? 1 : 0; 281 if ((printed > 0) && (printed + nlen + vlen + 1 > width)) { 282 switch ((int)printing) { 283 case (int)pr_terminfo: 284 case (int)pr_longnames: 285 (void) printf("\n"); 286 break; 287 case (int)pr_cap: 288 (void) printf(":\\\n"); 289 caplen += 1; 290 } 291 printed = 0; 292 } 293 if (printed == 0) { 294 switch ((int)printing) { 295 case (int)pr_terminfo: 296 (void) printf("\t"); 297 printed = 8; 298 break; 299 case (int)pr_cap: 300 (void) printf("\t:"); 301 printed = 9; 302 caplen += 2; 303 break; 304 case (int)pr_longnames: 305 (void) printf(" "); 306 printed = 2; 307 } 308 } else { 309 switch ((int)printing) { 310 case (int)pr_terminfo: 311 case (int)pr_longnames: 312 (void) printf(" "); 313 break; 314 case (int)pr_cap: 315 (void) printf(":"); 316 caplen += 1; 317 } 318 printed++; 319 } 320 if (value < 0) 321 switch ((int)printing) { 322 case (int)pr_terminfo: 323 (void) printf("%s@,", infoname); 324 printed += nlen + 2; 325 break; 326 case (int)pr_cap: 327 (void) printf("%s@", capname); 328 printed += nlen + 1; 329 caplen += nlen + 1; 330 break; 331 case (int)pr_longnames: 332 (void) printf("%s@,", fullname); 333 printed += nlen + 2; 334 } 335 else 336 switch ((int)printing) { 337 case (int)pr_terminfo: 338 (void) printf("%s,", infoname); 339 printed += nlen + 1; 340 break; 341 case (int)pr_cap: 342 (void) printf("%s", capname); 343 printed += nlen; 344 caplen += nlen; 345 break; 346 case (int)pr_longnames: 347 (void) printf("%s,", fullname); 348 printed += nlen + 1; 349 } 350 } 351 } 352 353 void 354 pr_bfooting(void) 355 { 356 if (!onecolumn && (printed > 0)) 357 switch ((int)printing) { 358 case (int)pr_terminfo: 359 case (int)pr_longnames: 360 (void) printf("\n"); 361 break; 362 case (int)pr_cap: 363 (void) printf(":\\\n"); 364 caplen += 1; 365 } 366 } 367 368 void 369 pr_nheading(void) 370 { 371 if (printing == pr_longnames) 372 (void) printf("\nnumbers\n"); 373 printed = 0; 374 } 375 376 /* 377 * Return the length of the number if it were printed out 378 * with %d. The number is guaranteed to be in the range 379 * 0..maxshort. 380 */ 381 static int 382 digitlen(int value) 383 { 384 return (value >= 10000 ? 5 : 385 value >= 1000 ? 4 : 386 value >= 100 ? 3 : 387 value >= 10 ? 2 : 388 value >= 0 ? 1 : 0); 389 } 390 391 void 392 pr_number(char *infoname, char *capname, char *fullname, int value) 393 { 394 int vlen; 395 size_t nlen; 396 397 if (printing == pr_cap && restrictterm && 398 !findcapname(capname, capnums, ncapnums)) 399 return; 400 401 if (onecolumn) { 402 if (value < 0) 403 switch ((int)printing) { 404 case (int)pr_terminfo: 405 (void) printf("\t%s@,\n", infoname); 406 break; 407 case (int)pr_cap: 408 (void) printf("\t:%s@:\\\n", capname); 409 caplen += 4 + strlen(capname); 410 break; 411 case (int)pr_longnames: 412 (void) printf(" %s @\n", fullname); 413 } 414 else 415 switch ((int)printing) { 416 case (int)pr_terminfo: 417 (void) printf("\t%s#%d,\n", infoname, 418 value); 419 break; 420 case (int)pr_cap: 421 (void) printf("\t:%s#%d:\\\n", 422 capname, value); 423 caplen += 4 + strlen(capname) + 424 digitlen(value); 425 break; 426 case (int)pr_longnames: 427 (void) printf(" %s = %d\n", fullname, 428 value); 429 } 430 } else { 431 switch ((int)printing) { 432 case (int)pr_terminfo: 433 nlen = strlen(infoname); 434 break; 435 case (int)pr_cap: 436 nlen = strlen(capname); 437 break; 438 case (int)pr_longnames: 439 nlen = strlen(fullname); 440 break; 441 } 442 vlen = digitlen(value); 443 if ((printed > 0) && (printed + nlen + vlen + 2 > width)) { 444 switch ((int)printing) { 445 case (int)pr_terminfo: 446 case (int)pr_longnames: 447 (void) printf("\n"); 448 break; 449 case (int)pr_cap: 450 (void) printf(":\\\n"); 451 caplen += 1; 452 } 453 printed = 0; 454 } 455 if (printed == 0) { 456 switch ((int)printing) { 457 case (int)pr_terminfo: 458 (void) printf("\t"); 459 printed = 8; 460 break; 461 case (int)pr_cap: 462 (void) printf("\t:"); 463 printed = 9; 464 caplen += 2; 465 break; 466 case (int)pr_longnames: 467 (void) printf(" "); 468 printed = 2; 469 } 470 } else { 471 switch ((int)printing) { 472 case (int)pr_terminfo: 473 case (int)pr_longnames: 474 (void) printf(" "); 475 break; 476 case (int)pr_cap: 477 (void) printf(":"); 478 caplen += 1; 479 } 480 printed++; 481 } 482 if (value < 0) { 483 switch ((int)printing) { 484 case (int)pr_terminfo: 485 (void) printf("%s@,", infoname); 486 printed += nlen + 2; 487 break; 488 case (int)pr_cap: 489 (void) printf("%s@", capname); 490 printed += nlen + 1; 491 caplen += nlen + 1; 492 break; 493 case (int)pr_longnames: 494 (void) printf("%s@,", fullname); 495 printed += nlen + 2; 496 } 497 } else 498 switch ((int)printing) { 499 case (int)pr_terminfo: 500 (void) printf("%s#%d,", infoname, 501 value); 502 printed += nlen + vlen + 2; 503 break; 504 case (int)pr_cap: 505 (void) printf("%s#%d", capname, value); 506 printed += nlen + vlen + 1; 507 caplen += nlen + vlen + 1; 508 break; 509 case (int)pr_longnames: 510 (void) printf("%s = %d,", fullname, 511 value); 512 printed += nlen + vlen + 4; 513 } 514 } 515 } 516 517 void 518 pr_nfooting(void) 519 { 520 if (!onecolumn && (printed > 0)) 521 switch ((int)printing) { 522 case (int)pr_terminfo: 523 case (int)pr_longnames: 524 (void) printf("\n"); 525 break; 526 case (int)pr_cap: 527 (void) printf(":\\\n"); 528 caplen += 1; 529 } 530 } 531 532 void 533 pr_sheading(void) 534 { 535 if (printing == pr_longnames) 536 (void) printf("\nstrings\n"); 537 printed = 0; 538 } 539 540 void 541 pr_string(char *infoname, char *capname, char *fullname, char *value) 542 { 543 char *evalue; 544 int badcapvalue; 545 size_t nlen, vlen; 546 547 if (printing == pr_cap) { 548 if (restrictterm && !findcapname(capname, capstrs, ncapstrs)) 549 return; 550 if (value) 551 value = infotocap(value, &badcapvalue); 552 } 553 554 if (onecolumn) { 555 if (value == NULL) 556 switch ((int)printing) { 557 case (int)pr_terminfo: 558 (void) printf("\t%s@,\n", infoname); 559 break; 560 case (int)pr_cap: 561 (void) printf("\t:%s@:\\\n", capname); 562 caplen += 4 + strlen(capname); 563 break; 564 case (int)pr_longnames: 565 (void) printf(" %s@\n", fullname); 566 } 567 else 568 switch ((int)printing) { 569 case (int)pr_terminfo: 570 (void) printf("\t%s=", infoname); 571 tpr(stdout, value); 572 (void) printf(",\n"); 573 break; 574 case (int)pr_cap: 575 (void) printf("\t:%s%s=", 576 badcapvalue ? "." : "", capname); 577 caplen += 3 + strlen(capname) + 578 (badcapvalue ? 1 : 0); 579 caplen += cpr(stdout, value); 580 (void) printf(":\\\n"); 581 caplen += 1; 582 break; 583 case (int)pr_longnames: 584 (void) printf(" %s = '", fullname); 585 tpr(stdout, value); 586 (void) printf("'\n"); 587 } 588 } else { 589 switch ((int)printing) { 590 case (int)pr_terminfo: 591 nlen = strlen(infoname); 592 break; 593 case (int)pr_cap: 594 nlen = strlen(capname); 595 if (badcapvalue) 596 nlen++; 597 break; 598 case (int)pr_longnames: 599 nlen = strlen(fullname); 600 } 601 if (value == NULL) 602 vlen = 1; 603 else 604 if (printing == pr_cap) 605 vlen = strlen(evalue = cexpand(value)); 606 else 607 vlen = strlen(evalue = iexpand(value)); 608 if ((printed > 0) && (printed + nlen + vlen + 1 > width)) { 609 switch ((int)printing) { 610 case (int)pr_terminfo: 611 case (int)pr_longnames: 612 (void) printf("\n"); 613 break; 614 case (int)pr_cap: 615 (void) printf(":\\\n"); 616 caplen += 1; 617 } 618 printed = 0; 619 } 620 if (printed == 0) { 621 switch ((int)printing) { 622 case (int)pr_terminfo: 623 (void) printf("\t"); 624 printed = 8; 625 break; 626 case (int)pr_cap: 627 (void) printf("\t:"); 628 printed = 9; 629 caplen += 2; 630 break; 631 case (int)pr_longnames: 632 (void) printf(" "); 633 printed = 2; 634 } 635 } else { 636 switch ((int)printing) { 637 case (int)pr_terminfo: 638 case (int)pr_longnames: 639 (void) printf(" "); 640 break; 641 case (int)pr_cap: 642 (void) printf(":"); 643 caplen += 1; 644 } 645 printed++; 646 } 647 if (value == NULL) { 648 switch ((int)printing) { 649 case (int)pr_terminfo: 650 (void) printf("%s@,", infoname); 651 printed += nlen + 2; 652 break; 653 case (int)pr_cap: 654 (void) printf("%s@", capname); 655 printed += nlen + 1; 656 caplen += nlen + 1; 657 break; 658 case (int)pr_longnames: 659 (void) printf("%s@,", fullname); 660 printed += nlen + 2; 661 } 662 } else 663 switch ((int)printing) { 664 case (int)pr_terminfo: 665 (void) printf("%s=%s,", infoname, 666 evalue); 667 printed += nlen + vlen + 2; 668 break; 669 case (int)pr_cap: 670 if (badcapvalue) { 671 (void) printf("."); 672 caplen += 1; 673 } 674 (void) printf("%s=%s", capname, 675 evalue); 676 printed += nlen + vlen + 1; 677 caplen += nlen + vlen + 1; 678 break; 679 case (int)pr_longnames: 680 (void) printf("%s = '%s',", fullname, 681 evalue); 682 printed += nlen + vlen + 6; 683 } 684 } 685 } 686 687 void 688 pr_sfooting(void) 689 { 690 if (onecolumn) { 691 if (printing == pr_cap) 692 (void) printf("\n"); 693 } else { 694 if (printed > 0) 695 switch ((int)printing) { 696 case (int)pr_terminfo: 697 case (int)pr_longnames: 698 (void) printf("\n"); 699 break; 700 case (int)pr_cap: 701 (void) printf(":\n"); 702 caplen += 1; 703 } 704 } 705 if (caplen >= 1024) { 706 (void) fprintf(stderr, "%s: WARNING: termcap entry is too " 707 "long!\n", progname); 708 } 709 710 if (printing == pr_longnames) 711 (void) printf("end of strings\n"); 712 } 713