tholm@uvicctr.UUCP (Terrence W. Holm) (05/18/88)
EFTH Minix report #9 - May 1988 - termcap(3) fixes
Following are some fixes for the termcap(3) supplied with Minix 1.2a.
The earlier version will get confused if $TERMCAP is defined, but
$TERM is not the same as the current terminal. The terminal name
was not compared correctly. Also the ^x escapes were incorrect.
We have also made a "man" page for the Minix termcap(3).
echo x - termcap.fix
gres '^X' '' > termcap.fix << '/'
X9a10,17
X>
X> /* efth 1988-Apr-29
X>
X> - Correct when TERM != name and TERMCAP is defined [tgetent]
X> - Correct the comparison for the terminal name [tgetent]
X> - Correct the value of ^x escapes [tgetstr]
X> */
X>
X44,52c52,64
X< if ((file = getenv("TERMCAP")) != (char *) NULL) {
X< if (*file != '/' &&
X< (cp = getenv("TERM")) != NULL && strcmp(name, cp) == 0) {
X< (void) strcpy(bp, file);
X< return(1);
X< }
X< } else
X< file = "/etc/termcap";
X< /* If TERM is NULL and TERMCAP is defined, then won't work (EFTH) */
X---
X>
X> /* Fixed problem: If TERM != name and TERMCAP was defined, */
X> /* then should look in /etc/termcap, but didn't. (efth) */
X>
X> if ( (file = getenv("TERMCAP")) == NULL )
X> file = "/etc/termcap";
X> else if ( *file != '/' )
X> if ( (cp = getenv("TERM")) != NULL && strcmp( name, cp ) == 0 ) {
X> strcpy( bp, file );
X> return( 1 );
X> } else
X> file = "/etc/termcap";
X>
X56c68,73
X< while (fgets(bp, 1024, fp) != NULL) {
X---
X>
X> while (fgets(bp, 1024, fp) != NULL) {
X> /* Read in the rest of the definition now (efth) */
X> while (*(cp = &bp[strlen(bp) - 2]) == '\\')
X> fgets(cp, 1024, fp);
X>
X62,64c79,81
X< if (strncmp(name, cp, len) == 0) {
X< while (*(cp = &bp[strlen(bp) - 2]) == '\\')
X< fgets(cp, 1024, fp);
X---
X>
X> /* Make sure "name" matches exactly (efth) */
X> if (strncmp(name, cp, len) == 0 && cp[len] == '|') {
X162c179
X< **area = *++cp - 'A';
X---
X> **area = *++cp - '@'; /* fix (efth)*/
/
echo x - termcap.3
gres '^X' '' > termcap.3 << '/'
XNAME
X termcap(3) - routines to read the termcap file
X
XSYNOPSIS
X int tgetent( buffer, name )
X char buffer[ 1024 ];
X char *name;
X
X int tgetflag( entry )
X char *entry;
X
X int tgetnum( entry )
X char *entry;
X
X char *tgetstr( entry, p )
X char *entry;
X char **p;
X
X char *tgoto( cm_string, column, line )
X char *cm_string;
X int column;
X int line;
X
X tputs( string, count, Putchar )
X char *string;
X int count;
X void (*Putchar)();
X
XDESCRIPTION
X To read a termcap description into memory, use tgetent().
X The capabilities of the terminal "name" will be copied
X to the "buffer". This buffer is used by tgetflag(), tgetnum()
X and tgetstr().
X
X This routine checks the $TERMCAP string in the environment,
X using the following algorithm,
X
X if ( $TERMCAP is undefined ) then
X search file /etc/termcap for "name"
X
X else if ( $TERMCAP starts with a '/' ) then
X search file $TERMCAP for "name"
X
X else if ( $TERM = "name" ) then
X use $TERMCAP as the termcap
X
X else
X search file /etc/termcap for "name"
X
X Note this means that when $TERM is changed $TERMCAP must be
X either updated or removed, see tset(1).
X
X On successful completion tgetent() returns 1. If it can not
X open the termcap file then -1 is returned. If there is no
X description for "name" then 0 is returned.
X
X READING ENTRIES
X
X To check for the presence of an entry in a description, use
X tgetflag(). This routine returns 1 if the capability is
X present, 0 if not and -1 for invalid calls.
X
X The "co" and "li" entries have a numeric value. A numeric
X entry is read by tgetnum(). If the entry is not specified
X then -1 is returned.
X
X Most entries are strings, and are read by tgetstr(). If
X the requested entry is found, then it is copied to **p.
X *p is incremented by the size of the entry. A pointer to
X the start of the string is returned if successful, NULL
X is returned if the entry was not found.
X
X GENERATING OUTPUT
X
X To position a cursor on the screen the routine tgoto() is
X used. This takes the "cm" string and a column and line
X number, and forms a string which can be sent to the terminal
X by using tputs(). If tgoto() encounters a problem, then the
X returned string is "OOPS". There are some special format
X commands recognized by tgoto(), see termcap(4) for details.
X
X All strings returned by tgetstr() or tgoto() should be
X output using tputs(). This performs the appropriate padding
X for different terminals under various Unix systems.
X For Minix, tputs() simply calls "Putchar()" for each
X character in "string".
X
X NOTES
X
X XTABS should be off while using termcap(3).
X
X See termcap(4) for a complete description of the termcap
X entries and the escape codes available for use within strings.
X
X
XFILES
X /etc/termcap The termcap entries
X
XSEE ALSO
X termcap(1), tset(1), termcap(4)
X
XBUGS
X tgetent() only checks the second terminal name in a description.
X
X tgoto() does not use BC or UP to avoid unpleasant characters.
X
X tgoto() is missing some format commands, including "%r".
X
X tputs() does not do padding under Minix.
/
--------------------------------------------------------------------
Edwin L. Froese
(in London for the month)
Terrence W. Holm
{uw-beaver,ubc-cs}!uvicctr!sirius!tholmtholm@uvicctr.UUCP (Terrence W. Holm) (05/18/88)
EFTH Minix report #10 - May 1988 - termcap(1)
This is an implementation of termcap(1) that we wrote for Minix.
Please consider this a public domain program.
Termcap(1) prints out some of the information from /etc/termcap
in a more readable form. This posting might be a bit premature
as most Minix users are not yet to the stage of debugging termcap
entries - but you might want to keep this for later use.
For those people who are using termcap(3): termcap(1) can be
extended to include any other entries you want to see displayed.
Also included is our /etc/termcap and our own termcap(4) "man" page,
in which we describe the subset of Unix entries that we currently
have defined. We hope this will help some Minix users.
echo x - termcap.1
gres '^X' '' > termcap.1 << '/'
XNAME
X termcap(1) - display the current termcap settings
X
XSYNOPSIS
X termcap [ type ]
X
XDESCRIPTION
X Prints out the termcap capabilities as described in
X termcap(4). If "type" is not supplied then $TERM is
X used.
X
XFILES
X /etc/termcap terminal capabilities
X
XSEE ALSO
X termcap(3), termcap(4)
X
XBUGS
X Only a subset of the Unix termcap entries are recognized.
X
X The definitions for "k0" through "k5" were influenced by
X the unique case of running Minix on an IBM PC/AT.
/
echo x - termcap.c
gres '^X' '' > termcap.c << '/'
X/****************************************************************/
X/* */
X/* termcap(1) */
X/* */
X/* Display the current termcap settings. */
X/* */
X/****************************************************************/
X/* origination 1988-Apr-28 T. Holm */
X/****************************************************************/
X
X
X#include <stdio.h>
X
X
X#define TC_BUFFER 1024 /* Size of termcap(3) buffer */
X
X
Xchar *getenv();
Xchar *tgetstr();
X
X
X
X
X
X
X/****************************************************************/
X/* */
X/* termcap [ type ] */
X/* */
X/* Prints out all of the termcap capabilities as described */
X/* in termcap(4). If "type" is not supplied then $TERM is */
X/* used. */
X/* */
X/****************************************************************/
X
X
Xmain( argc, argv )
X int argc;
X char *argv[];
X
X {
X char *term;
X char buffer[ TC_BUFFER ];
X
X
X /* Check for an argument */
X
X if ( argc > 2 )
X Error( "Usage: %s [ type ]\n", argv[0] );
X
X if ( argc == 2 )
X term = argv[1];
X else
X term = getenv( "TERM" );
X
X if ( term == NULL )
X Error( "termcap: $TERM is not defined\n", "" );
X
X
X /* Read in the termcap entry */
X
X if ( tgetent( buffer, term ) != 1 )
X Error( "termcap: No termcap entry for %s\n", term );
X
X
X /* Print out the entry's contents */
X
X printf( "TERM = %s\n\n", term );
X
X if ( tgetflag( "am" ) == 1 )
X printf( "End of line wraps to next line (am)\n" );
X
X if ( tgetflag( "bs" ) == 1 )
X printf( "Ctrl/H performs a backspace (bs)\n" );
X
X printf( "Number of columns (co) = %d\n", tgetnum( "co" ) );
X printf( "Number of lines (li) = %d\n", tgetnum( "li" ) );
X
X Print( "Clear to end of line", "ce" );
X Print( "Clear to end of screen", "cd" );
X Print( "Clear the whole screen", "cl" );
X
X Print( "Start \"stand out\" mode", "so" );
X Print( "End \"stand out\" mode", "se" );
X Print( "Start underscore mode", "us" );
X Print( "End underscore mode", "ue" );
X Print( "Start blinking mode", "mb" );
X Print( "Start bold mode", "md" );
X Print( "Start reverse mode", "mr" );
X Print( "Return to normal mode", "me" );
X
X Print( "Scroll backwards", "sr" );
X Print( "Cursor motion", "cm" );
X
X Print( "Up one line", "up" );
X Print( "Down one line", "do" );
X Print( "Left one space", "le" );
X Print( "Right one space", "nd" );
X Print( "Move to top left corner", "ho" );
X
X Print( "Generated by \"UP\"", "ku" );
X Print( "Generated by \"DOWN\"", "kd" );
X Print( "Generated by \"LEFT\"", "kl" );
X Print( "Generated by \"RIGHT\"", "kr" );
X Print( "Generated by \"HOME\"", "kh" );
X Print( "Generated by \"END\"", "k0" );
X Print( "Generated by \"PGUP\"", "k1" );
X Print( "Generated by \"PGDN\"", "k2" );
X Print( "Generated by numeric \"+\"", "k3" );
X Print( "Generated by numeric \"-\"", "k4" );
X Print( "Generated by numeric \"5\"", "k5" );
X
X exit( 0 );
X }
X
X
X
X
X
X
X/****************************************************************/
X/* */
X/* Print( comment, name ) */
X/* */
X/* If a termcap entry exists for "name", then */
X/* print out "comment" and the entry. Control */
X/* characters are printed as ^x. */
X/* */
X/****************************************************************/
X
X
XPrint( comment, name )
X char *comment;
X char *name;
X
X {
X char entry[ 50 ];
X char *p = entry;
X
X if ( tgetstr( name, &p ) == NULL )
X return;
X
X printf( "%-32s (%s) = ", comment, name );
X
X for ( p = entry; *p != '\0'; ++p )
X if ( *p < ' ' )
X printf( "^%c", *p + '@' );
X else if ( *p == '\177' )
X printf( "^?" );
X else
X putchar( *p );
X
X putchar( '\n' );
X }
X
X
X
X
X
X
X/****************************************************************/
X/* */
X/* Error( message, arg ) */
X/* */
X/* Printf the "message" and abort. */
X/* */
X/****************************************************************/
X
X
XError( message, arg )
X char *message;
X char *arg;
X
X {
X fprintf( stderr, message, arg );
X exit( 1 );
X }
/
echo x - termcap.4
gres '^X' '' > termcap.4 << '/'
XNAME
X termcap(4) - terminal capabilities
X
XSYNOPSIS
X /etc/termcap
X
XDESCRIPTION
X The "termcap" file contains definitions which yield the
X properties of different types of terminals. Each definition
X has many optional entries, for example, the number of lines
X on the device and the string to clear the screen.
X
X Each program which wishes to treat the output device as
X something more powerful than a stream of bytes, should use
X the termcap(3) routines. These routines look in the "termcap"
X capability file and retrieve the properties of the current
X terminal.
X
X The user should make sure that a definition exists in the
X "termcap" file, and then set the environment variable $TERM
X to the name of the current terminal.
X
X
X BUILDING YOUR OWN TERMCAP ENTRY
X
X Each "termcap" entry consists of a list of alternate names for
X the terminal, followed by codes describing its properties. The
X names are separated by '|' characters, and the definitions by
X ':'s. If a line ends with a '\' then the entry continues on the
X following line.
X
X For historical reasons, the first name is two characters long.
X The last name is simply a comment. Only the second name is
X currently checked by the Minix termcap(3). An example is,
X
X mx|minix|console:\
X :bs:co#80:li#24:\
X :cd=\E[0J:cl=\E[H\E[0J:\
X :so=\E[7m:se=\E[0m:\
X :sr=\EM:\
X :cm=\E[%i%d;%dH:\
X :ho=\E[H:
X
X
X The first two codes do not take any arguments, include
X them if your terminal has the corresponding function.
X
X am Right off end of line wraps to next line
X bs Ctrl/H performs a backspace
X
X
X Define the size of the display.
X
X co# Number of columns
X li# Number of lines
X
X
X All of the following codes take a string argument. Within
X strings certain escape codes are allowed:
X
X ^x Ctrl/x
X \xxx Octal code
X \200 Null (^@)
X \b Backspace (^H)
X \t Tab (^I)
X \n Newline (^J)
X \f Formfeed (^L)
X \r Return (^M)
X \E Escape (^[)
X \072 :
X \\ \
X \^ ^
X
X
X There are three codes for different clearing functions.
X
X ce Clear to end of line
X cd Clear to end of screen
X cl Clear the whole screen
X
X
X If the terminal can change the mode of the display for
X subsequently output characters, then set the relevant
X entries described below. The "mx" entries are for
X ANSI compatible terminals.
X
X so Start "stand out" mode (usually reverse)
X se End "stand out" mode
X us Start underscore mode (sometimes bold)
X ue End underscore mode
X mb Start blinking mode
X md Start bold mode
X mr Start reverse mode (same as "so")
X me Return to normal mode
X
X
X The following is only available on a few terminals.
X
X sr Scroll backwards
X
X
X There is a definition for cursor motion.
X
X cm Cursor motion
X
X The string for "cm" acts like a printf() command, with the
X destination line and column as arguments. There are some '%'
X format commands which control the printing of the output
X string when tgoto(3) is used:
X
X %d Print as a number (%2d)
X %+c Print as a character (after adding 'c')
X %i Increment before output
X %% Print a '%'
X
X
X The following are simpler cursor movements, try to
X define these if "cm" is not appropriate for your terminal.
X
X up Up one line
X do Down one line
X le Left one space
X nd Right one space
X ho Move to top left corner
X
X
X Each of the following are set to the string generated by
X certain special function keys on the keyboard. If the key
X does not exist, then no definition need be supplied.
X
X ku String generated by "UP"
X kd String generated by "DOWN"
X kl String generated by "LEFT"
X kr String generated by "RIGHT"
X kh String generated by "HOME"
X k0 String generated by "END"
X k1 String generated by "PGUP"
X k2 String generated by "PGDN"
X k3 String generated by numeric "+"
X k4 String generated by numeric "-"
X k5 String generated by numeric "5"
X
X
X NOTES
X
X Try to at least define "co#", "li#", "cl", "so", "se"
X and "ho". Programs should be able to always find these
X entries.
X
X The following commands also require additional termcap
X entries:
X
X blank "cm"
X elle "cm"
X ic "cm"
X mined "cm", "sr"
X
X
XFILES
X /etc/termcap The termcap entries
X
XSEE ALSO
X termcap(1), termcap(3)
X
XBUGS
X Some termcaps allow delay parameters. The Minix termcap(3)
X does not handle them.
X
X There are some useful "%" format commands that are not described
X here because tgoto(3) does not support them.
X
X Mined does not call termcap(3), but has the strings built-in.
X
X Not all entries are checked by users of termcap(3).
X Especially the "kx" entries.
X
X If a terminal does not support "cm", then it is the application's
X responsibility to use "ho", "do" and "nd".
X
X The entries described in termcap(4) are only a subset of the
X ones available under Unix.
/
echo x - termcap
gres '^X' '' > termcap << '/'
Xsl|lpr|line printer:\
X :co#132:li#66:\
X :cl=\f:\
X :so=^N:se=^O:\
X :do=^J:\
X :le=^H:nd= :\
X :ho=\f:
Xmx|minix|minix console:\
X :bs:\
X :co#80:li#24:\
X :cd=\E[0J:cl=\E[H\E[0J:\
X :so=\E[7m:se=\E[0m:\
X :us=\E[4m:ue=\E[0m:\
X :mb=\E[5m:md=\E[1m:\
X :mr=\E[7m:me=\E[0m:\
X :sr=\EM:\
X :cm=\E[%i%d;%dH:\
X :ho=\E[H:\
X :ku=\E[A:kd=\E[B:\
X :kl=\E[D:kr=\E[C:\
X :kh=\E[H:k0=\E[Y:\
X :k1=\E[V:k2=\E[U:\
X :k3=\E[T:k4=\E[S:\
X :k5=\E[G:
Xd0|vt100|DEC vt100:\
X :am:bs:\
X :co#80:li#24:\
X :ce=\E[K:cd=\E[J:cl=\E[;H\E[2J:\
X :so=\E[7m:se=\E[m:\
X :us=\E[4m:ue=\E[m:\
X :mb=\E[5m:md=\E[1m:\
X :mr=\E[7m:me=\E[m:\
X :sr=\EM:\
X :cm=\E[%i%d;%dH:\
X :up=\E[A:do=^J:\
X :le=^H:nd=\E[C:\
X :ho=\E[H:\
X :ku=\E[A:kd=\E[B:\
X :kl=\E[D:kr=\E[C:\
X :k1=\EOP:k2=\EOQ:\
X :k3=\EOR:k4=\EOS:
Xla|adm3a|lsi adm3a (emulated on a vc4404):\
X :am:bs:\
X :co#80:li#24:\
X :ce=\ET:cd=\EY:cl=^Z:\
X :so=\E):se=\E(:\
X :cm=\E=%+ %+ :\
X :up=^K:do=^J:\
X :le=^H:nd=^L:\
X :ho=^^:\
X :ku=^K:kd=^J:\
X :kl=^H:kr=^L:\
X :kh=^^:k0=\E":\
X :k1=\EP:k2=\EQ:\
X :k3=\ER:k4=\E :\
X :k5=\E!:
XM8|vc404|volker-craig 404:\
X :am:bs:\
X :co#80:li#24:\
X :ce=^V:cd=^W:cl=^X:\
X :so=^N:se=^O:\
X :cm=^P%+ %+ :\
X :up=^Z:do=^J:\
X :le=^H:nd=^U:\
X :ho=^Y:\
X :ku=^Z:kd=^J:kl=^H:kr=^U:\
X :kh=^Y:
/
--------------------------------------------------------------------
Edwin L. Froese
(in London for the month)
Terrence W. Holm
{uw-beaver,ubc-cs}!uvicctr!sirius!tholmtholm@uvicctr.UUCP (Terrence W. Holm) (07/08/88)
While checking the MINIX 1.3 library patches I noticed that my fix to termcap(3) has not been applied. Besides missing a couple of features, the old termcap(3) does not compare terminal names properly (ie. "vt100" == "vt100-np") and the ^x escapes are wrong in tgetstr(3). So here are the patches again, to be applied to the 1.3 termcap(3): -------------------------------------------------------------------- EFTH Minix report #9 - May 1988 - termcap(3) fixes Following are some fixes for the termcap(3) supplied with Minix 1.2a/1.3. The earlier version will get confused if $TERMCAP is defined, but $TERM is not the same as the current terminal. The terminal name was not compared correctly. Also the ^x escapes were incorrect. We have also made a "man" page for the Minix termcap(3) [available from the archives.] -------------------------------------------------------------------- 9a10,17 > > /* efth 1988-Apr-29 > > - Correct when TERM != name and TERMCAP is defined [tgetent] > - Correct the comparison for the terminal name [tgetent] > - Correct the value of ^x escapes [tgetstr] > */ > 44,54c52,73 < if ((file = getenv("TERMCAP")) != (char *) NULL) { < if (*file != '/' && < (cp = getenv("TERM")) != NULL && strcmp(name, cp) == 0) { < (void) strcpy(bp, file); < return(1); < } < } else < file = "/etc/termcap"; < if ((fp = fopen(file, "r")) == (FILE *) NULL) < return(-1); < while (fgets(bp, 1024, fp) != NULL) { --- > > /* Fixed problem: If TERM != name and TERMCAP was defined, */ > /* then should look in /etc/termcap, but didn't. (efth) */ > > if ( (file = getenv("TERMCAP")) == NULL ) > file = "/etc/termcap"; > else if ( *file != '/' ) > if ( (cp = getenv("TERM")) != NULL && strcmp( name, cp ) == 0 ) { > strcpy( bp, file ); > return( 1 ); > } else > file = "/etc/termcap"; > > > if ((fp = fopen(file, "r")) == (FILE *) NULL) > return(-1); > > while (fgets(bp, 1024, fp) != NULL) { > /* Read in the rest of the definition now (efth) */ > while (*(cp = &bp[strlen(bp) - 2]) == '\\') > fgets(cp, 1024, fp); > 60,62c79,81 < if (strncmp(name, cp, len) == 0) { < while (*(cp = &bp[strlen(bp) - 2]) == '\\') < fgets(cp, 1024, fp); --- > > /* Make sure "name" matches exactly (efth) */ > if (strncmp(name, cp, len) == 0 && cp[len] == '|') { 160c179 < **area = *++cp - 'A'; --- > **area = *++cp - '@'; /* fix (efth)*/ -------------------------------------------------------------------- Edwin L. Froese uw-beaver!ubc-cs!mprg!handel!froese Terrence W. Holm uw-beaver!ubc-cs!uvicctr!sirius!tholm
tholm@uvicctr.UUCP (Terrence W. Holm) (10/26/88)
EFTH MINIX report #53 - October 1988 - termcap(3) fix Another termcap(3) problem: short definitions following long definitions obtain features of the previous line. The following fixes this. ---------------------------------------------------------- 11c11 < /* efth 1988-Apr-29 --- > /* Terrence W. Holm May, Sep, Oct 1988 16a17 > - Fixed end of definition test [tgetnum/flag/str] 101c102,103 < for (++cp ; *cp ; cp++) { --- > while ( *cp ) { > cp++; 134c136,137 < for (++cp ; *cp ; cp++) { --- > while ( *cp ) { > cp++; 163c166,167 < for (++cp ; *cp ; cp++) { --- > while ( *cp ) { > cp++; ---------------------------------------------------------- Terrence W. Holm uw-beaver!uvicctr!tholm
x110ws%TAMUNIX.BITNET@CORNELLC.CIT.CORNELL.EDU (Wally Strzelec) (12/07/88)
hello... can someone point me to or send me a termcap that will work
with elle.
Also I would like to get a copy of kermit for the IBM version of minix,
if someone could just send me a ftp address it would be very much
appreciated.
See you
Wally Strzelec
<x110ws@tamunix.tamu.edu>
You will become rich and famous unless you don't.