pc-hack

PC HACK 3.61 source code (archival)
git clone http://frotz.net/git/pc-hack.git
Log | Files | Refs

tgetent.c (7749B)


      1 /************************************************************************
      2  *									*
      3  *			Copyright (c) 1982, Fred Fish			*
      4  *			    All Rights Reserved				*
      5  *									*
      6  *	This software and/or documentation is released for public	*
      7  *	distribution for personal, non-commercial use only.		*
      8  *	Limited rights to use, modify, and redistribute are hereby	*
      9  *	granted for non-commercial purposes, provided that all		*
     10  *	copyright notices remain intact and all changes are clearly	*
     11  *	documented.  The author makes no warranty of any kind with	*
     12  *	respect to this product and explicitly disclaims any implied	*
     13  *	warranties of merchantability or fitness for any particular	*
     14  *	purpose.							*
     15  *									*
     16  ************************************************************************
     17  */
     18 
     19 
     20 /*
     21  *  LIBRARY FUNCTION
     22  *
     23  *	tgetent   load buffer with entry for specified terminal
     24  *
     25  *  KEY WORDS
     26  *
     27  *	termcap functions
     28  *	utility routines
     29  *
     30  *  SYNOPSIS
     31  *
     32  *	int tgetent(bp,name)
     33  *	char *bp;
     34  *	char *name;
     35  *
     36  *  DESCRIPTION
     37  *
     38  *	Extracts the entry for terminal <name> from the termcap file
     39  *	and places it in the character buffer <bp>.   It is currently
     40  *	assumed that bp is at least 1024 characters.  If the entry in
     41  *	the termcap file is larger than 1023 characters the excess
     42  *	characters will be discarded and appropriate status will
     43  *	be returned.
     44  *
     45  *	Also note that since bp is used by other termcap
     46  *	routines, the storage associated with the termcap entry
     47  *	cannot be freed until all termcap calls are completed.
     48  *
     49  *	Tgetent can be directed to look in a file other than
     50  *	the default (/etc/termcap) by defining an environment
     51  *	variable called TERMCAP to be the pathname of the desired
     52  *	termcap file.  This is useful for debugging new entries.
     53  *	NOTE: the pathname MUST begin with a '/' character.
     54  *
     55  *	Also, if the string assigned to TERMCAP does not begin with
     56  *	a '/' and if the environment variable TERM matches <name> then
     57  *	the string assigned to TERMCAP is copied to buffer <bp> 
     58  *	instead of reading a termcap file.
     59  *	
     60  *  RETURNS
     61  *
     62  *	-1  if the termcap file cannot be opened
     63  *	 0  if no entry in termcap file matches <name>
     64  *	 1  if extraction is successful with no errors
     65  *	 2  if extraction is successful but entry truncated
     66  *
     67  *  SEE ALSO
     68  *
     69  *	tgetnum   extract numeric type capability
     70  *	tgetflag  test boolean type capability
     71  *	tgetstr   get string value of capability
     72  *
     73  *  AUTHOR
     74  *
     75  *	Fred Fish
     76  *
     77  */
     78 
     79 #include <stdio.h>
     80 
     81 #define TRUE 1
     82 #define FALSE 0
     83 #define BUFSIZE 1024			/* Assumed size of external buffer */
     84 
     85 #define NO_FILE	 -1			/* Returned if can't open file */
     86 #define NO_ENTRY  0			/* Returned if can't find entry */
     87 #define SUCCESS   1			/* Returned if entry found ok */
     88 #define TRUNCATED 2			/* Returned if entry found but trunc */
     89 
     90 # ifdef DGK
     91 # define DEFAULT_ROOT "termcap"		/* name without path component */
     92   FILE *fopenp();
     93 # endif
     94 # define DEFAULT_FILE "/etc/termcap"	/* default termcap filename */
     95 
     96 char *_tcpbuf;				/* Place to remember buffer pointer */
     97 
     98 /*
     99  *  PSEUDO CODE
    100  *
    101  *	Begin tgetent
    102  *	    Erase any previous buffer contents.
    103  *	    Remember the buffer pointer.
    104  *	    If termcap file is not found then
    105  *		If buffer was filled anyway then
    106  *		    Return SUCCESS.
    107  *		Else
    108  *		    Return NO_FILE.
    109  *		End if
    110  *	    Else
    111  *		While records left to process
    112  *		    If this is entry is what we want then
    113  *			Close the termcap file.
    114  *			If entry was truncated then
    115  *			    Return TRUNCATED status
    116  *			Else
    117  *			    Return SUCCESS status.
    118  *			End if
    119  *		    End if
    120  *		End while
    121  *		Return NO_ENTRY status.
    122  *	    End if
    123  *	End tgetent
    124  *			
    125  */
    126 
    127 int tgetent(bp,name)
    128 char *bp;				/* Pointer to buffer (1024 char min) */
    129 char *name;				/* Pointer to terminal entry to find */
    130 {
    131     FILE *fp, *find_file();
    132 
    133     *bp = NULL;
    134     _tcpbuf = bp;
    135     if ((fp = find_file(bp)) == NULL) {
    136 	if (*bp != NULL) {
    137 	    return(SUCCESS);
    138 	} else {
    139 	    return(NO_FILE);
    140 	}
    141     } else {
    142 	while (fgetlr(bp,BUFSIZE,fp)) {
    143 	    if (gotcha(bp,name)) {
    144 		fclose(fp);
    145 		if (bp[strlen(bp)-1] != '\n') {
    146 		    return(TRUNCATED);
    147 		} else {
    148 		    return(SUCCESS);
    149 		}
    150 	    }
    151 	}
    152 	return(NO_ENTRY);
    153     }
    154 }
    155 
    156 /*
    157  *  INTERNAL FUNCTION
    158  *
    159  *	find_file    find the termcap file and open it if possible
    160  *
    161  *  KEY WORDS
    162  *
    163  *	internal functions
    164  *	find_file
    165  *
    166  *  SYNOPSIS
    167  *
    168  *	static FILE *find_file(bp)
    169  *	char *bp;
    170  *
    171  *  DESCRIPTION
    172  *
    173  *	Attempts to locate and open the termcap file.  Also handles
    174  *	using the environment TERMCAP string as the actual buffer
    175  *	(that's why bp has to be an input parameter).
    176  *
    177  *	If TERMCAP is defined an begins with a '/' character then
    178  *	it is taken to be the pathname of the termcap file and
    179  *	an attempt is made to open it.  If this fails then
    180  *	the default termcap file is used instead.
    181  *
    182  *	If TERMCAP is defined but does not begin with a '/' then
    183  *	it is assumed to be the actual buffer contents provided
    184  *	that <name> matches the environment variable TERM.
    185  *
    186  *  BUGS
    187  *
    188  *	There is currently no way to be sure which termcap
    189  *	file was opened since the default will always be
    190  *	tried.
    191  *
    192  */
    193 
    194 /*
    195  *  PSEUDO CODE
    196  *
    197  *	Begin find_file
    198  *	    If there is a TERMCAP environment string then
    199  *		If the string is not null then
    200  *		    If the string is a pathname then
    201  *			If that file is opened successfully then
    202  *			    Return its pointer.
    203  *			End if
    204  *		    Else
    205  *			If there is a TERM environment string then
    206  *			    If TERM matches <name> then
    207  *				Copy TERMCAP string to buffer.
    208  *				Return NULL for no file.
    209  *			    End if
    210  *			End if
    211  *		    End if
    212  *		End if
    213  *	    End if
    214  *	    Open default termcap file and return results.
    215  *	End find_file
    216  *
    217  */
    218 
    219 static FILE *find_file(bp)
    220 char *bp;
    221 {
    222     FILE *fp, *fopen();
    223     char *cp, *ncp, *getenv();
    224 
    225     if ((cp = getenv("TERMCAP")) != NULL) {
    226 	if (*cp != NULL) {
    227 	    if (*cp == '/' || *cp == '\\') {
    228 		if ((fp = fopen(cp,"r")) != NULL) {
    229 		    return(fp);
    230 		}
    231 	    } else {
    232 		if ((ncp = getenv("TERM")) != NULL) {
    233 		    if (strcmp(cp,ncp) == 0) {
    234 			strcpy(bp,cp);
    235 			return((FILE *)NULL);
    236 		    }
    237 		}
    238 	    }
    239 	}
    240     }
    241 # ifdef DGK
    242 	/* Try current directory, then /etc/termcap, then along the path
    243 	 */
    244 	if (fp = fopen(DEFAULT_ROOT, "r"))
    245 		return fp;
    246 	else if (fp = fopen(DEFAULT_FILE, "r"))
    247 		return fp;
    248 	else
    249 		return fopenp(DEFAULT_ROOT, "r", NULL);
    250 # else
    251     return(fopen(DEFAULT_FILE,"r"));
    252 # endif
    253 }
    254 
    255 /*
    256  *  INTERNAL FUNCTION
    257  *
    258  *	gotcha   test to see if entry is for specified terminal
    259  *
    260  *  SYNOPSIS
    261  *
    262  *	gotcha(bp,name)
    263  *	char *bp;
    264  *	char *name;
    265  *
    266  *  DESCRIPTION
    267  *
    268  *	Tests to see if the entry in buffer bp matches the terminal
    269  *	specified by name.  Returns TRUE if match is detected, FALSE
    270  *	otherwise.
    271  *
    272  */
    273 
    274 /*
    275  *  PSEUDO CODE
    276  *
    277  *	Begin gotcha
    278  *	    If buffer character is comment character then
    279  *		Return FALSE since remainder is comment
    280  *	    Else
    281  *		Initialize name scan pointer.
    282  *		Compare name and buffer until end or mismatch.
    283  *		If valid terminators for both name and buffer strings
    284  *		    Return TRUE since a match was found.
    285  *		Else
    286  *		    Find next non-name character in buffer.
    287  *		    If not an alternate name separater character
    288  *			Return FALSE since no more names to check.
    289  *		    Else
    290  *			Test next name and return results.
    291  *		    End if
    292  *		End if
    293  *	    End if
    294  *	End gotcha
    295  *
    296  */
    297 
    298 gotcha(bp,name)
    299 char *bp;
    300 char *name;
    301 {
    302     char *np;
    303  
    304     if (*bp == '#') {
    305 	return(FALSE);
    306     } else {
    307 	np = name;
    308 	while (*np == *bp && *np != NULL) {np++; bp++;}
    309 	if (*np == NULL && (*bp == NULL || *bp == '|' || *bp == ':')) {
    310 	    return(TRUE);
    311 	} else {
    312 	    while (*bp != NULL && *bp != ':' && *bp != '|') {bp++;}
    313 	    if (*bp != '|') {
    314 		return(FALSE);
    315 	    } else {
    316 		return(gotcha(++bp,name));
    317 	    }
    318 	}
    319     }
    320 }