|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ T t ┃
Length: 10688 (0x29c0) Types: TextFile Names: »tgetent.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/micrognu/sys/vms/termcap/tgetent.c«
/************************************************************************ * * * Copyright (c) 1982, Fred Fish * * All Rights Reserved * * * * This software and/or documentation is released for public * * distribution for personal, non-commercial use only. * * Limited rights to use, modify, and redistribute are hereby * * granted for non-commercial purposes, provided that all * * copyright notices remain intact and all changes are clearly * * documented. The author makes no warranty of any kind with * * respect to this product and explicitly disclaims any implied * * warranties of merchantability or fitness for any particular * * purpose. * * * ************************************************************************ */ /* * Modified: * 30-Apr-86 Mic Kaczmarczik ...!ihnp4!seismo!ut-sally!ut-ngp!mic * Instead of using VAX C getenv("TERM"), which does not * return the value of logical name "TERM", translate the * logical name by hand. * 11-Oct-86 Mic Kaczmarczik ...!ihnp4!seismo!ut-sally!ut-ngp!mic * Support tc capability to allow the library to use standard * termcaps. Rewrote tgetent to look for tc capability * and add new terminal definition to the caller's buffer. * This makes it rather possible to overflow the caller's * buffer, but the library doesn't make any claim that it * won't overwrite the buffer anyway... */ \f /* * LIBRARY FUNCTION * * tgetent load buffer with entry for specified terminal * * KEY WORDS * * termcap functions * utility routines * * SYNOPSIS * * int tgetent(bp,name) * char *bp; * char *name; * * DESCRIPTION * * Extracts the entry for terminal <name> from the termcap file * and places it in the character buffer <bp>. It is currently * assumed that bp is at least 1024 characters. If the entry in * the termcap file is larger than 1023 characters the excess * characters will be discarded and appropriate status will * be returned. * * Also note that since bp is used by other termcap * routines, the storage associated with the termcap entry * cannot be freed until all termcap calls are completed. * * Tgetent can be directed to look in a file other than * the default (/etc/termcap) by defining an environment * variable called TERMCAP to be the pathname of the desired * termcap file. This is useful for debugging new entries. * NOTE: the pathname MUST begin with a '/' character. * * Also, if the string assigned to TERMCAP does not begin with * a '/' and if the environment variable TERM matches <name> then * the string assigned to TERMCAP is copied to buffer <bp> * instead of reading a termcap file. * * RETURNS * * -1 if the termcap file cannot be opened * 0 if no entry in termcap file matches <name> * 1 if extraction is successful with no errors * 2 if extraction is successful but entry truncated * * SEE ALSO * * tgetnum extract numeric type capability * tgetflag test boolean type capability * tgetstr get string value of capability * * AUTHOR * * Fred Fish * */ #include <stdio.h> #define TRUE 1 #define FALSE 0 #define BUFSIZE 1024 /* Assumed size of external buffer */ #define NO_FILE -1 /* Returned if can't open file */ #define NO_ENTRY 0 /* Returned if can't find entry */ #define SUCCESS 1 /* Returned if entry found ok */ #define TRUNCATED 2 /* Returned if entry found but trunc */ #define DEFAULT_FILE "/etc/termcap" /* default termcap filename */ #ifdef VAXC #define index strchr #endif char *_tcpbuf; /* Place to remember buffer pointer */ FILE *fp, *find_file(); /* Termcap file */ extern char *index(); /* * PSEUDO CODE * * Begin tgetent * Erase any previous buffer contents. * Remember the buffer pointer. * If termcap file is not found then * If buffer was filled anyway then * Return SUCCESS. * Else * Return NO_FILE. * End if * Else * Find entry associated with name * While an entry was found and limit not reached * If no tc capability found Then * Exit while loop with status = SUCCESS * Else * Call getent to get entry indicated by tc= * If entry not found then * Exit loop with status != SUCCESS * End if * Concatenate entry into buffer * End If * End while * End if * Close termcap file * Return status code * End tgetent * */ int tgetent(bp,name) char *bp; char *name; { char *tc, *tcbufp, tcbuf[80], termbuf[BUFSIZE], *tgetstr(); char *bufp, *cp; /* current start of buffer */ int limit = 10; /* maximum nesting */ int status; /* return from getent() */ *bp = '\0'; /* clear buffer */ _tcpbuf = bp; /* save base of buffer */ /* Look for termcap file. If NULL, find_file may have found a */ /* a valid termcap string in the environment variable TERMCAP. */ /* If non-null, attempt to find the entry in the termcap file */ if ((fp = find_file(bp)) == NULL) { if (*bp != NULL) return(SUCCESS); else return(NO_FILE); } status = getent(bp, name);/* look for main entry */ /* Start looking for tc capabilities in the termcap. If * found, concatenate the entry for the new terminal to the * current buffer and try again. To avoid infinite loops, * allow only 10 loops through this process. */ while ((status == SUCCESS) && limit--) { /* look for tc capability. If none found, exit loop */ tcbufp = tcbuf; if (((tc = tgetstr("tc",&tcbufp)) == NULL) || (*tc == '\0')) { status = SUCCESS;/* no more tc= entries */ break; } /* Attempt to get next entry. Exit loop if unsuccessful */ if ((status = getent(termbuf, tcbuf)) != SUCCESS) break; /* Copy new entry into buffer, right at "tc=" */ for (bufp = bp; *bufp; bufp++) /* find tc= */ if ((*bufp=='t') && (bufp[1]=='c') && (bufp[2]=='=')) break; if ((cp = index(termbuf,':')) == NULL) cp = termbuf; strcpy(bufp, cp + 1); } /* close termcap file and return the status */ fclose(fp); return status; } \f /* * INTERNAL FUNCTION * * getent find termcap entry in termcap file * * KEY WORDS * * internal functions * getent * * SYNOPSIS * * static int getent(bp,name) * char *bp; * char *name; * * DESCRIPTION * * Getent is called by tgetent each time tgetent attempts to * read a capability from the termcap database file. Places * the entry in the buffer pointed to by bp * * * PSEUDOCODE * * Begin Getent * Seek to beginning of termcap file * Clear buffer * While records left to process * If this is entry is what we want then * If entry was truncated then * Return TRUNCATED status * Else * Return SUCCESS status. * End if * End if * End while * Return NO_ENTRY status. * End */ static int getent(bp,name) char *bp; /* Pointer to buffer (1024 char min) */ char *name; /* Pointer to terminal entry to find */ { *bp = '\0'; /* clear buffer */ lseek(fileno(fp), 0L, 0l); /* rewind termcap file */ while (fgetlr(bp,BUFSIZE,fp)) { if (gotcha(bp,name)) { if (bp[strlen(bp)-1] != '\n') { return(TRUNCATED); } else { return(SUCCESS); } } } return(NO_ENTRY); } \f /* * INTERNAL FUNCTION * * find_file find the termcap file and open it if possible * * KEY WORDS * * internal functions * find_file * * SYNOPSIS * * static FILE *find_file(bp) * char *bp; * * DESCRIPTION * * Attempts to locate and open the termcap file. Also handles * using the environment TERMCAP string as the actual buffer * (that's why bp has to be an input parameter). * * If TERMCAP is defined an begins with a '/' character then * it is taken to be the pathname of the termcap file and * an attempt is made to open it. If this fails then * the default termcap file is used instead. * * If TERMCAP is defined but does not begin with a '/' then * it is assumed to be the actual buffer contents provided * that <name> matches the environment variable TERM. * * BUGS * * There is currently no way to be sure which termcap * file was opened since the default will always be * tried. * */ \f /* * PSEUDO CODE * * Begin find_file * If there is a TERMCAP environment string then * If the string is not null then * If the string is a pathname then * If that file is opened successfully then * Return its pointer. * End if * Else * If there is a TERM environment string then * If TERM matches <name> then * Copy TERMCAP string to buffer. * Return NULL for no file. * End if * End if * End if * End if * End if * Open default termcap file and return results. * End find_file * */ #ifdef VAXC char *trnlnm(); #endif static FILE *find_file(bp) char *bp; { FILE *fp, *fopen(); char *cp, *ncp, *getenv(), vmsname[132]; if ((cp = getenv("TERMCAP")) != NULL) { if (*cp != NULL) { if (*cp == '/') { if ((fp = fopen(cp,"r")) != NULL) { return(fp); } } else { #ifdef VAXC if ((ncp = trnlnm("TERM")) != NULL) { #else if ((ncp = getenv("TERM")) != NULL) { #endif if (strcmp(cp,ncp) == 0) { strcpy(bp,cp); return((FILE *)NULL); } } } } } return(fopen(DEFAULT_FILE,"r")); } \f /* * INTERNAL FUNCTION * * gotcha test to see if entry is for specified terminal * * SYNOPSIS * * gotcha(bp,name) * char *bp; * char *name; * * DESCRIPTION * * Tests to see if the entry in buffer bp matches the terminal * specified by name. Returns TRUE if match is detected, FALSE * otherwise. * */ \f /* * PSEUDO CODE * * Begin gotcha * If buffer character is comment character then * Return FALSE since remainder is comment * Else * Initialize name scan pointer. * Compare name and buffer until end or mismatch. * If valid terminators for both name and buffer strings * Return TRUE since a match was found. * Else * Find next non-name character in buffer. * If not an alternate name separater character * Return FALSE since no more names to check. * Else * Test next name and return results. * End if * End if * End if * End gotcha * */ gotcha(bp,name) char *bp; char *name; { char *np; if (*bp == '#') { return(FALSE); } else { np = name; while (*np == *bp && *np != NULL) {np++; bp++;} if (*np == NULL && (*bp == NULL || *bp == '|' || *bp == ':')) { return(TRUE); } else { while (*bp != NULL && *bp != ':' && *bp != '|') {bp++;} if (*bp != '|') { return(FALSE); } else { return(gotcha(++bp,name)); } } } }