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