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