⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 read_termcap.c

📁 ncurses 库 可能有用酒用 没用就算了 我觉得还可以用
💻 C
📖 第 1 页 / 共 3 页
字号:
    char *dummy = NULL;    char **fname;    char *home;    int i;    char pathbuf[PBUFSIZ];	/* holds raw path of filenames */    char *pathvec[PVECSIZ];	/* to point to names in pathbuf */    char **pvec;		/* holds usable tail of path vector */    NCURSES_CONST char *termpath;    string_desc desc;    fname = pathvec;    pvec = pathvec;    tbuf = bp;    p = pathbuf;    cp = use_terminfo_vars()? getenv("TERMCAP") : NULL;    /*     * TERMCAP can have one of two things in it.  It can be the name of a file     * to use instead of /etc/termcap.  In this case it better start with a     * "/".  Or it can be an entry to use so we don't have to read the file.      * In this case it has to already have the newlines crunched out.  If     * TERMCAP does not hold a file name then a path of names is searched     * instead.  The path is found in the TERMPATH variable, or becomes     * "$HOME/.termcap /etc/termcap" if no TERMPATH exists.     */    _nc_str_init(&desc, pathbuf, sizeof(pathbuf));    if (cp == NULL) {	_nc_safe_strcpy(&desc, get_termpath());    } else if (!is_pathname(cp)) {	/* TERMCAP holds an entry */	if ((termpath = get_termpath()) != 0) {	    _nc_safe_strcat(&desc, termpath);	} else {	    char temp[PBUFSIZ];	    temp[0] = 0;	    if ((home = getenv("HOME")) != 0 && *home != '\0'		&& strchr(home, ' ') == 0		&& strlen(home) < sizeof(temp) - 10) {	/* setup path */		sprintf(temp, "%s/", home);	/* $HOME first */	    }	    /* if no $HOME look in current directory */	    strcat(temp, ".termcap");	    _nc_safe_strcat(&desc, temp);	    _nc_safe_strcat(&desc, " ");	    _nc_safe_strcat(&desc, get_termpath());	}    } else {			/* user-defined name in TERMCAP */	_nc_safe_strcat(&desc, cp);	/* still can be tokenized */    }    *fname++ = pathbuf;		/* tokenize path into vector of names */    while (*++p) {	if (*p == ' ' || *p == NCURSES_PATHSEP) {	    *p = '\0';	    while (*++p)		if (*p != ' ' && *p != NCURSES_PATHSEP)		    break;	    if (*p == '\0')		break;	    *fname++ = p;	    if (fname >= pathvec + PVECSIZ) {		fname--;		break;	    }	}    }    *fname = 0;			/* mark end of vector */    if (is_pathname(cp)) {	if (_nc_cgetset(cp) < 0) {	    return (TC_SYS_ERR);	}    }    i = _nc_cgetent(&dummy, lineno, pathvec, name);    /* ncurses' termcap-parsing routines cannot handle multiple adjacent     * empty fields, and mistakenly use the last valid cap entry instead of     * the first (breaks tc= includes)     */    if (i >= 0) {	char *pd, *ps, *tok;	int endflag = FALSE;	char *list[1023];	size_t n, count = 0;	pd = bp;	ps = dummy;	while (!endflag && (tok = get_tc_token(&ps, &endflag)) != 0) {	    bool ignore = FALSE;	    for (n = 1; n < count; n++) {		char *s = list[n];		if (s[0] == tok[0]		    && s[1] == tok[1]) {		    ignore = TRUE;		    break;		}	    }	    if (ignore != TRUE) {		list[count++] = tok;		pd = copy_tc_token(pd, tok, TBUFSIZ - (2 + pd - bp));		if (pd == 0) {		    i = -1;		    break;		}		*pd++ = ':';		*pd = '\0';	    }	}    }    FreeIfNeeded(dummy);    FreeIfNeeded(the_source);    the_source = 0;    /* This is not related to the BSD cgetent(), but to fake up a suitable     * filename for ncurses' error reporting.  (If we are not using BSD     * cgetent, then it is the actual filename).     */    if (i >= 0) {	if ((the_source = strdup(pathvec[i])) != 0)	    *sourcename = the_source;    }    return (i);}#endif /* USE_BSD_TGETENT */#endif /* USE_GETCAP */#define MAXPATHS	32/* * Add a filename to the list in 'termpaths[]', checking that we really have * a right to open the file. */#if !USE_GETCAPstatic intadd_tc(char *termpaths[], char *path, int count){    char *save = strchr(path, NCURSES_PATHSEP);    if (save != 0)	*save = '\0';    if (count < MAXPATHS	&& _nc_access(path, R_OK) == 0) {	termpaths[count++] = path;	T(("Adding termpath %s", path));    }    termpaths[count] = 0;    if (save != 0)	*save = NCURSES_PATHSEP;    return count;}#define ADD_TC(path, count) filecount = add_tc(termpaths, path, count)#endif /* !USE_GETCAP */NCURSES_EXPORT(int)_nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp){    int found = FALSE;    ENTRY *ep;#if USE_GETCAP_CACHE    char cwd_buf[PATH_MAX];#endif#if USE_GETCAP    char *p, tc[TBUFSIZ];    static char *source;    static int lineno;    T(("read termcap entry for %s", tn));    if (strlen(tn) == 0	|| strcmp(tn, ".") == 0	|| strcmp(tn, "..") == 0	|| _nc_pathlast(tn) != 0) {	T(("illegal or missing entry name '%s'", tn));	return 0;    }    if (use_terminfo_vars() && (p = getenv("TERMCAP")) != 0	&& !is_pathname(p) && _nc_name_match(p, tn, "|:")) {	/* TERMCAP holds a termcap entry */	strncpy(tc, p, sizeof(tc) - 1);	tc[sizeof(tc) - 1] = '\0';	_nc_set_source("TERMCAP");    } else {	/* we're using getcap(3) */	if (_nc_tgetent(tc, &source, &lineno, tn) < 0)	    return (ERR);	_nc_curr_line = lineno;	_nc_set_source(source);    }    _nc_read_entry_source((FILE *) 0, tc, FALSE, FALSE, NULLHOOK);#else    /*     * Here is what the 4.4BSD termcap(3) page prescribes:     *     * It will look in the environment for a TERMCAP variable.  If found, and     * the value does not begin with a slash, and the terminal type name is the     * same as the environment string TERM, the TERMCAP string is used instead     * of reading a termcap file.  If it does begin with a slash, the string is     * used as a path name of the termcap file to search.  If TERMCAP does not     * begin with a slash and name is different from TERM, tgetent() searches     * the files $HOME/.termcap and /usr/share/misc/termcap, in that order,     * unless the environment variable TERMPATH exists, in which case it     * specifies a list of file pathnames (separated by spaces or colons) to be     * searched instead.     *     * It goes on to state:     *     * Whenever multiple files are searched and a tc field occurs in the     * requested entry, the entry it names must be found in the same file or     * one of the succeeding files.     *     * However, this restriction is relaxed in ncurses; tc references to     * previous files are permitted.     *     * This routine returns 1 if an entry is found, 0 if not found, and -1 if     * the database is not accessible.     */    FILE *fp;    char *tc, *termpaths[MAXPATHS];    int filecount = 0;    int j, k;    bool use_buffer = FALSE;    bool normal = TRUE;    char tc_buf[1024];    char pathbuf[PATH_MAX];    char *copied = 0;    char *cp;    struct stat test_stat[MAXPATHS];    termpaths[filecount] = 0;    if (use_terminfo_vars() && (tc = getenv("TERMCAP")) != 0) {	if (is_pathname(tc)) {	/* interpret as a filename */	    ADD_TC(tc, 0);	    normal = FALSE;	} else if (_nc_name_match(tc, tn, "|:")) {	/* treat as a capability file */	    use_buffer = TRUE;	    (void) sprintf(tc_buf, "%.*s\n", (int) sizeof(tc_buf) - 2, tc);	    normal = FALSE;	}    }    if (normal) {		/* normal case */	char envhome[PATH_MAX], *h;	copied = strdup(get_termpath());	for (cp = copied; *cp; cp++) {	    if (*cp == NCURSES_PATHSEP)		*cp = '\0';	    else if (cp == copied || cp[-1] == '\0') {		ADD_TC(cp, filecount);	    }	}#define PRIVATE_CAP "%s/.termcap"	if (use_terminfo_vars() && (h = getenv("HOME")) != NULL && *h != '\0'	    && (strlen(h) + sizeof(PRIVATE_CAP)) < PATH_MAX) {	    /* user's .termcap, if any, should override it */	    (void) strcpy(envhome, h);	    (void) sprintf(pathbuf, PRIVATE_CAP, envhome);	    ADD_TC(pathbuf, filecount);	}    }    /*     * Probably /etc/termcap is a symlink to /usr/share/misc/termcap.     * Avoid reading the same file twice.     */#if HAVE_LINK    for (j = 0; j < filecount; j++) {	bool omit = FALSE;	if (stat(termpaths[j], &test_stat[j]) != 0	    || (test_stat[j].st_mode & S_IFMT) != S_IFREG) {	    omit = TRUE;	} else {	    for (k = 0; k < j; k++) {		if (test_stat[k].st_dev == test_stat[j].st_dev		    && test_stat[k].st_ino == test_stat[j].st_ino) {		    omit = TRUE;		    break;		}	    }	}	if (omit) {	    T(("Path %s is a duplicate", termpaths[j]));	    for (k = j + 1; k < filecount; k++) {		termpaths[k - 1] = termpaths[k];		test_stat[k - 1] = test_stat[k];	    }	    --filecount;	    --j;	}    }#endif    /* parse the sources */    if (use_buffer) {	_nc_set_source("TERMCAP");	/*	 * We don't suppress warning messages here.  The presumption is	 * that since it's just a single entry, they won't be a pain.	 */	_nc_read_entry_source((FILE *) 0, tc_buf, FALSE, FALSE, NULLHOOK);    } else {	int i;	for (i = 0; i < filecount; i++) {	    T(("Looking for %s in %s", tn, termpaths[i]));	    if (_nc_access(termpaths[i], R_OK) == 0		&& (fp = fopen(termpaths[i], "r")) != (FILE *) 0) {		_nc_set_source(termpaths[i]);		/*		 * Suppress warning messages.  Otherwise you get 400 lines of		 * crap from archaic termcap files as ncurses complains about		 * all the obsolete capabilities.		 */		_nc_read_entry_source(fp, (char *) 0, FALSE, TRUE, NULLHOOK);		(void) fclose(fp);	    }	}    }    if (copied != 0)	free(copied);#endif /* USE_GETCAP */    if (_nc_head == 0)	return (ERR);    /* resolve all use references */    _nc_resolve_uses2(TRUE, FALSE);    /* find a terminal matching tn, if we can */#if USE_GETCAP_CACHE    if (getcwd(cwd_buf, sizeof(cwd_buf)) != 0) {	_nc_set_writedir((char *) 0);	/* note: this does a chdir */#endif	for_entry_list(ep) {	    if (_nc_name_match(ep->tterm.term_names, tn, "|:")) {		/*		 * Make a local copy of the terminal capabilities, delinked		 * from the list.		 */		*tp = ep->tterm;		_nc_delink_entry(_nc_head, &(ep->tterm));		free(ep);		/*		 * OK, now try to write the type to user's terminfo directory. 		 * Next time he loads this, it will come through terminfo.		 *		 * Advantage:  Second and subsequent fetches of this entry will		 * be very fast.		 *		 * Disadvantage:  After the first time a termcap type is loaded		 * by its user, editing it in the /etc/termcap file, or in		 * TERMCAP, or in a local ~/.termcap, will be ineffective		 * unless the terminfo entry is explicitly removed.		 */#if USE_GETCAP_CACHE		(void) _nc_write_entry(tp);#endif		found = TRUE;		break;	    }	}#if USE_GETCAP_CACHE	chdir(cwd_buf);    }#endif    return (found);}#elseexternNCURSES_EXPORT(void)_nc_read_termcap(void);NCURSES_EXPORT(void)_nc_read_termcap(void){}#endif /* PURE_TERMINFO */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -