2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A/* Copyright (c) 1988 AT&T */
2N/A/* All Rights Reserved */
2N/A
2N/A/*
2N/A * University Copyright- Copyright (c) 1982, 1986, 1988
2N/A * The Regents of the University of California
2N/A * All Rights Reserved
2N/A *
2N/A * University Acknowledgment- Portions of this document are derived from
2N/A * software developed by the University of California, Berkeley, and its
2N/A * contributors.
2N/A */
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A#include <stdlib.h>
2N/A#include <string.h>
2N/A#include <sys/types.h>
2N/A#include "curses_inc.h"
2N/A#include "print.h"
2N/A#include <signal.h> /* use this file to determine if this is SVR4.0 system */
2N/A
2N/A#ifdef SIGSTOP /* SVR4.0 and beyond */
2N/A#define _ULIBTI "/usr/share/lib/terminfo"
2N/A#else
2N/A#define _ULIBTI "/usr/lib/terminfo"
2N/A#endif
2N/A
2N/Achar *progname;
2N/A
2N/A/* global variables */
2N/Astatic enum printtypes printing = pr_none;
2N/Astatic int onecolumn = 0; /* print a single column */
2N/Astatic int width = 60; /* width of multi-column printing */
2N/Astatic int restrictterm = 1; /* restrict termcap names */
2N/A
2N/A/* local variables */
2N/Astatic int printed = 0;
2N/Astatic size_t caplen = 0;
2N/A
2N/Avoid
2N/Apr_init(enum printtypes type)
2N/A{
2N/A printing = type;
2N/A}
2N/A
2N/Avoid
2N/Apr_onecolumn(int onoff)
2N/A{
2N/A onecolumn = onoff;
2N/A}
2N/A
2N/Avoid
2N/Apr_width(int nwidth)
2N/A{
2N/A if (nwidth > 0)
2N/A width = nwidth;
2N/A}
2N/A
2N/Avoid
2N/Apr_caprestrict(int onoff)
2N/A{
2N/A restrictterm = onoff;
2N/A}
2N/A
2N/Astatic char capbools[] =
2N/A "ambsbwdadbeoeshchshzinkmmimsncnsosptulxbxnxoxsxt";
2N/Astatic int ncapbools = sizeof (capbools) / sizeof (capbools[0]);
2N/A
2N/Astatic char capnums[] =
2N/A "codBdCdFdNdTknlipbsgug";
2N/Astatic int ncapnums = sizeof (capnums) / sizeof (capnums[0]);
2N/A
2N/Astatic char capstrs[] =
2N/A "ALDCDLDOICLERISFSRUPaealasbcbtcdcechclcmcsctcvdcdldmdsedeifshoi1i2i"
2N/A "cifimipisk0k1k2k3k4k5k6k7k8k9kbkdkekhklkokrkskul0l1l2l3l4l5l6l7l"
2N/A "8l9ndnlpcr1r2r3rcrfrpscsesosrsttetitsucueupusvbvevivs";
2N/Astatic int ncapstrs = sizeof (capstrs) / sizeof (capstrs[0]);
2N/A
2N/Astatic int
2N/Afindcapname(char *capname, char *caplist, int listsize)
2N/A{
2N/A int low = 0, mid, high = listsize - 2;
2N/A while (low <= high) {
2N/A mid = (low + high) / 4 * 2;
2N/A if (capname[0] == caplist[mid]) {
2N/A if (capname[1] == caplist[mid + 1])
2N/A return (1);
2N/A else if (capname[1] < caplist[mid + 1])
2N/A high = mid - 2;
2N/A else
2N/A low = mid + 2;
2N/A } else if (capname[0] < caplist[mid])
2N/A high = mid - 2;
2N/A else
2N/A low = mid + 2;
2N/A }
2N/A return (0);
2N/A/*
2N/A * for (; *caplist; caplist += 2)
2N/A * if (caplist[0] == capname[0] && caplist[1] == capname[1])
2N/A * return (1);
2N/A * return (0);
2N/A */
2N/A}
2N/A
2N/A/*
2N/A * Print out the first line of an entry.
2N/A */
2N/Avoid
2N/Apr_heading(char *term, char *synonyms)
2N/A{
2N/A int do_print = 0; /* Can we print the path of the file ? */
2N/A char buffer[512]; /* Holds search pathname */
2N/A FILE *work_fp; /* Used to try and open the files */
2N/A char tail[4]; /* Used for terminfo pathname suffix */
2N/A char *terminfo; /* The value of $TERMINFO */
2N/A
2N/A
2N/A /*
2N/A * Try to obtain $TERMINFO
2N/A */
2N/A terminfo = getenv("TERMINFO");
2N/A
2N/A if (term == (char *)0)
2N/A term = "";
2N/A /*
2N/A * Build the suffix for this device
2N/A */
2N/A tail[0] = '/';
2N/A tail[1] = *term;
2N/A tail[2] = '/';
2N/A tail[3] = '\0';
2N/A
2N/A /*
2N/A * If we have it - use it, otherwise use /usr/share/lib/terminfo
2N/A * as base directory
2N/A */
2N/A if (terminfo != NULL)
2N/A (void) sprintf(buffer, "%s%s%s", terminfo, tail, term);
2N/A else
2N/A (void) sprintf(buffer, "%s%s%s", _ULIBTI, tail, term);
2N/A
2N/A /*
2N/A * Attempt to open the file.
2N/A */
2N/A if ((work_fp = fopen(buffer, "rF")) == NULL) {
2N/A /*
2N/A * Open failed. If we were looking in /usr/share/lib/terminfo
2N/A * we are done, otherwise look there next.
2N/A */
2N/A if (strncmp(buffer, _ULIBTI, strlen(_ULIBTI)) == 0) {
2N/A /*
2N/A * We are done. Not in /usr/share/lib/terminfo,
2N/A * and $TERMINFO is not set.
2N/A */
2N/A (void) fprintf(stderr, "Error: Term \"%s\" not "
2N/A "found in %s\n", term, _ULIBTI);
2N/A } else {
2N/A /*
2N/A * Check /usr/share/lib/terminfo last. If this fails,
2N/A * all hope is lost as we know it is not in $TERMINFO.
2N/A */
2N/A (void) sprintf(buffer, "%s%s%s", _ULIBTI, tail, term);
2N/A
2N/A if ((work_fp = fopen(buffer, "rF")) == NULL) {
2N/A /*
2N/A * All hope is lost
2N/A */
2N/A (void) fprintf(stderr, "Error: Term \"%s\" not "
2N/A "found in %s or %s\n", term, _ULIBTI,
2N/A getenv("TERMINFO"));
2N/A } else do_print = 1;
2N/A }
2N/A } else do_print = 1;
2N/A
2N/A /*
2N/A * If we found it - print the comment(after closing the file)
2N/A */
2N/A if (do_print && *term) {
2N/A (void) fclose(work_fp);
2N/A (void) printf("# Reconstructed via infocmp from file: "
2N/A "%s\n", buffer);
2N/A }
2N/A
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A (void) printf("%s,\n", synonyms);
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf("%s:\\\n", synonyms);
2N/A caplen = strlen(synonyms) + 1;
2N/A break;
2N/A case (int)pr_longnames:
2N/A (void) printf("Terminal type %s\n", term);
2N/A (void) printf(" %s\n", synonyms);
2N/A break;
2N/A }
2N/A}
2N/A
2N/Avoid
2N/Apr_bheading(void)
2N/A{
2N/A if (printing == pr_longnames)
2N/A (void) printf("flags\n");
2N/A printed = 0;
2N/A}
2N/A
2N/Avoid
2N/Apr_boolean(char *infoname, char *capname, char *fullname, int value)
2N/A{
2N/A int vlen;
2N/A size_t nlen;
2N/A
2N/A if (printing == pr_cap && restrictterm &&
2N/A !findcapname(capname, capbools, ncapbools))
2N/A return;
2N/A
2N/A if (onecolumn) {
2N/A if (value < 0)
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A (void) printf("\t%s@,\n", infoname);
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf("\t:%s@:\\\n", capname);
2N/A caplen += 4 + strlen(capname);
2N/A break;
2N/A case (int)pr_longnames:
2N/A (void) printf(" %s@\n", fullname);
2N/A }
2N/A else
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A (void) printf("\t%s,\n", infoname);
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf("\t:%s:\\\n", capname);
2N/A caplen += 3 + strlen(capname);
2N/A break;
2N/A case (int)pr_longnames:
2N/A (void) printf(" %s\n", fullname);
2N/A }
2N/A } else {
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo: nlen = strlen(infoname);
2N/A break;
2N/A case (int)pr_cap: nlen = strlen(capname);
2N/A break;
2N/A case (int)pr_longnames:
2N/A nlen = strlen(fullname);
2N/A break;
2N/A }
2N/A vlen = (value < 0) ? 1 : 0;
2N/A if ((printed > 0) && (printed + nlen + vlen + 1 > width)) {
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A case (int)pr_longnames:
2N/A (void) printf("\n");
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf(":\\\n");
2N/A caplen += 1;
2N/A }
2N/A printed = 0;
2N/A }
2N/A if (printed == 0) {
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A (void) printf("\t");
2N/A printed = 8;
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf("\t:");
2N/A printed = 9;
2N/A caplen += 2;
2N/A break;
2N/A case (int)pr_longnames:
2N/A (void) printf(" ");
2N/A printed = 2;
2N/A }
2N/A } else {
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A case (int)pr_longnames:
2N/A (void) printf(" ");
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf(":");
2N/A caplen += 1;
2N/A }
2N/A printed++;
2N/A }
2N/A if (value < 0)
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A (void) printf("%s@,", infoname);
2N/A printed += nlen + 2;
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf("%s@", capname);
2N/A printed += nlen + 1;
2N/A caplen += nlen + 1;
2N/A break;
2N/A case (int)pr_longnames:
2N/A (void) printf("%s@,", fullname);
2N/A printed += nlen + 2;
2N/A }
2N/A else
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A (void) printf("%s,", infoname);
2N/A printed += nlen + 1;
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf("%s", capname);
2N/A printed += nlen;
2N/A caplen += nlen;
2N/A break;
2N/A case (int)pr_longnames:
2N/A (void) printf("%s,", fullname);
2N/A printed += nlen + 1;
2N/A }
2N/A }
2N/A}
2N/A
2N/Avoid
2N/Apr_bfooting(void)
2N/A{
2N/A if (!onecolumn && (printed > 0))
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A case (int)pr_longnames:
2N/A (void) printf("\n");
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf(":\\\n");
2N/A caplen += 1;
2N/A }
2N/A}
2N/A
2N/Avoid
2N/Apr_nheading(void)
2N/A{
2N/A if (printing == pr_longnames)
2N/A (void) printf("\nnumbers\n");
2N/A printed = 0;
2N/A}
2N/A
2N/A/*
2N/A * Return the length of the number if it were printed out
2N/A * with %d. The number is guaranteed to be in the range
2N/A * 0..maxshort.
2N/A */
2N/Astatic int
2N/Adigitlen(int value)
2N/A{
2N/A return (value >= 10000 ? 5 :
2N/A value >= 1000 ? 4 :
2N/A value >= 100 ? 3 :
2N/A value >= 10 ? 2 :
2N/A value >= 0 ? 1 : 0);
2N/A}
2N/A
2N/Avoid
2N/Apr_number(char *infoname, char *capname, char *fullname, int value)
2N/A{
2N/A int vlen;
2N/A size_t nlen;
2N/A
2N/A if (printing == pr_cap && restrictterm &&
2N/A !findcapname(capname, capnums, ncapnums))
2N/A return;
2N/A
2N/A if (onecolumn) {
2N/A if (value < 0)
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A (void) printf("\t%s@,\n", infoname);
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf("\t:%s@:\\\n", capname);
2N/A caplen += 4 + strlen(capname);
2N/A break;
2N/A case (int)pr_longnames:
2N/A (void) printf(" %s @\n", fullname);
2N/A }
2N/A else
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A (void) printf("\t%s#%d,\n", infoname,
2N/A value);
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf("\t:%s#%d:\\\n",
2N/A capname, value);
2N/A caplen += 4 + strlen(capname) +
2N/A digitlen(value);
2N/A break;
2N/A case (int)pr_longnames:
2N/A (void) printf(" %s = %d\n", fullname,
2N/A value);
2N/A }
2N/A } else {
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A nlen = strlen(infoname);
2N/A break;
2N/A case (int)pr_cap:
2N/A nlen = strlen(capname);
2N/A break;
2N/A case (int)pr_longnames:
2N/A nlen = strlen(fullname);
2N/A break;
2N/A }
2N/A vlen = digitlen(value);
2N/A if ((printed > 0) && (printed + nlen + vlen + 2 > width)) {
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A case (int)pr_longnames:
2N/A (void) printf("\n");
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf(":\\\n");
2N/A caplen += 1;
2N/A }
2N/A printed = 0;
2N/A }
2N/A if (printed == 0) {
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A (void) printf("\t");
2N/A printed = 8;
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf("\t:");
2N/A printed = 9;
2N/A caplen += 2;
2N/A break;
2N/A case (int)pr_longnames:
2N/A (void) printf(" ");
2N/A printed = 2;
2N/A }
2N/A } else {
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A case (int)pr_longnames:
2N/A (void) printf(" ");
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf(":");
2N/A caplen += 1;
2N/A }
2N/A printed++;
2N/A }
2N/A if (value < 0) {
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A (void) printf("%s@,", infoname);
2N/A printed += nlen + 2;
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf("%s@", capname);
2N/A printed += nlen + 1;
2N/A caplen += nlen + 1;
2N/A break;
2N/A case (int)pr_longnames:
2N/A (void) printf("%s@,", fullname);
2N/A printed += nlen + 2;
2N/A }
2N/A } else
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A (void) printf("%s#%d,", infoname,
2N/A value);
2N/A printed += nlen + vlen + 2;
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf("%s#%d", capname, value);
2N/A printed += nlen + vlen + 1;
2N/A caplen += nlen + vlen + 1;
2N/A break;
2N/A case (int)pr_longnames:
2N/A (void) printf("%s = %d,", fullname,
2N/A value);
2N/A printed += nlen + vlen + 4;
2N/A }
2N/A }
2N/A}
2N/A
2N/Avoid
2N/Apr_nfooting(void)
2N/A{
2N/A if (!onecolumn && (printed > 0))
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A case (int)pr_longnames:
2N/A (void) printf("\n");
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf(":\\\n");
2N/A caplen += 1;
2N/A }
2N/A}
2N/A
2N/Avoid
2N/Apr_sheading(void)
2N/A{
2N/A if (printing == pr_longnames)
2N/A (void) printf("\nstrings\n");
2N/A printed = 0;
2N/A}
2N/A
2N/Avoid
2N/Apr_string(char *infoname, char *capname, char *fullname, char *value)
2N/A{
2N/A char *evalue;
2N/A int badcapvalue;
2N/A size_t nlen, vlen;
2N/A
2N/A if (printing == pr_cap) {
2N/A if (restrictterm && !findcapname(capname, capstrs, ncapstrs))
2N/A return;
2N/A if (value)
2N/A value = infotocap(value, &badcapvalue);
2N/A }
2N/A
2N/A if (onecolumn) {
2N/A if (value == NULL)
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A (void) printf("\t%s@,\n", infoname);
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf("\t:%s@:\\\n", capname);
2N/A caplen += 4 + strlen(capname);
2N/A break;
2N/A case (int)pr_longnames:
2N/A (void) printf(" %s@\n", fullname);
2N/A }
2N/A else
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A (void) printf("\t%s=", infoname);
2N/A tpr(stdout, value);
2N/A (void) printf(",\n");
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf("\t:%s%s=",
2N/A badcapvalue ? "." : "", capname);
2N/A caplen += 3 + strlen(capname) +
2N/A (badcapvalue ? 1 : 0);
2N/A caplen += cpr(stdout, value);
2N/A (void) printf(":\\\n");
2N/A caplen += 1;
2N/A break;
2N/A case (int)pr_longnames:
2N/A (void) printf(" %s = '", fullname);
2N/A tpr(stdout, value);
2N/A (void) printf("'\n");
2N/A }
2N/A } else {
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A nlen = strlen(infoname);
2N/A break;
2N/A case (int)pr_cap:
2N/A nlen = strlen(capname);
2N/A if (badcapvalue)
2N/A nlen++;
2N/A break;
2N/A case (int)pr_longnames:
2N/A nlen = strlen(fullname);
2N/A }
2N/A if (value == NULL)
2N/A vlen = 1;
2N/A else
2N/A if (printing == pr_cap)
2N/A vlen = strlen(evalue = cexpand(value));
2N/A else
2N/A vlen = strlen(evalue = iexpand(value));
2N/A if ((printed > 0) && (printed + nlen + vlen + 1 > width)) {
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A case (int)pr_longnames:
2N/A (void) printf("\n");
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf(":\\\n");
2N/A caplen += 1;
2N/A }
2N/A printed = 0;
2N/A }
2N/A if (printed == 0) {
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A (void) printf("\t");
2N/A printed = 8;
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf("\t:");
2N/A printed = 9;
2N/A caplen += 2;
2N/A break;
2N/A case (int)pr_longnames:
2N/A (void) printf(" ");
2N/A printed = 2;
2N/A }
2N/A } else {
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A case (int)pr_longnames:
2N/A (void) printf(" ");
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf(":");
2N/A caplen += 1;
2N/A }
2N/A printed++;
2N/A }
2N/A if (value == NULL) {
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A (void) printf("%s@,", infoname);
2N/A printed += nlen + 2;
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf("%s@", capname);
2N/A printed += nlen + 1;
2N/A caplen += nlen + 1;
2N/A break;
2N/A case (int)pr_longnames:
2N/A (void) printf("%s@,", fullname);
2N/A printed += nlen + 2;
2N/A }
2N/A } else
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A (void) printf("%s=%s,", infoname,
2N/A evalue);
2N/A printed += nlen + vlen + 2;
2N/A break;
2N/A case (int)pr_cap:
2N/A if (badcapvalue) {
2N/A (void) printf(".");
2N/A caplen += 1;
2N/A }
2N/A (void) printf("%s=%s", capname,
2N/A evalue);
2N/A printed += nlen + vlen + 1;
2N/A caplen += nlen + vlen + 1;
2N/A break;
2N/A case (int)pr_longnames:
2N/A (void) printf("%s = '%s',", fullname,
2N/A evalue);
2N/A printed += nlen + vlen + 6;
2N/A }
2N/A }
2N/A}
2N/A
2N/Avoid
2N/Apr_sfooting(void)
2N/A{
2N/A if (onecolumn) {
2N/A if (printing == pr_cap)
2N/A (void) printf("\n");
2N/A } else {
2N/A if (printed > 0)
2N/A switch ((int)printing) {
2N/A case (int)pr_terminfo:
2N/A case (int)pr_longnames:
2N/A (void) printf("\n");
2N/A break;
2N/A case (int)pr_cap:
2N/A (void) printf(":\n");
2N/A caplen += 1;
2N/A }
2N/A }
2N/A if (caplen >= 1024) {
2N/A (void) fprintf(stderr, "%s: WARNING: termcap entry is too "
2N/A "long!\n", progname);
2N/A }
2N/A
2N/A if (printing == pr_longnames)
2N/A (void) printf("end of strings\n");
2N/A}