コード例 #1
0
ファイル: getcap.c プロジェクト: robertbachmann/openbsd-libc
int
cgetfirst(char **buf, char **db_array)
{

	(void)cgetclose();
	return (cgetnext(buf, db_array));
}
コード例 #2
0
ファイル: printcap.c プロジェクト: 2asoft/freebsd
void
lastprinter(void)
{
	cgetclose();
}
コード例 #3
0
ファイル: getcap.c プロジェクト: robertbachmann/openbsd-libc
/*
 * Cgetnext() gets either the first or next entry in the logical database
 * specified by db_array.  It returns 0 upon completion of the database, 1
 * upon returning an entry with more remaining, and -1 if an error occurs.
 */
int
cgetnext(char **cap, char **db_array)
{
	size_t len, otopreclen = topreclen;
	int c, serrno, status = -1;
	char buf[BUFSIZ], nbuf[BSIZE];
	char *b_end, *bp, *r_end, *rp;
	char *record = NULL;
	char *otoprec = toprec;
	u_int dummy;
	off_t pos;

	if (dbp == NULL)
		dbp = db_array;

	if (pfp == NULL && (pfp = fopen(*dbp, "re")) == NULL)
		goto done;

	/*
	 * Check if we have an unused top record from cgetset().
	 */
	if (toprec && !gottoprec) {
		gottoprec = 1;
		record = toprec;
		goto lookup;
	}

	/*
	 * Allocate first chunk of memory.
	 */
	if ((record = malloc(BFRAG)) == NULL)
		goto done;
	r_end = record + BFRAG;

	/*
	 * Find the next capability record
	 */
	/*
	 * Loop invariants:
	 *	There is always room for one more character in record.
	 *	R_end always points just past end of record.
	 *	Rp always points just past last character in record.
	 *	B_end always points just past last character in buf.
	 *	Bp always points at next character in buf.
	 */
	b_end = buf;
	bp = buf;
	for (;;) {
		/*
		 * Read in a line implementing (\, newline)
		 * line continuation.
		 */
		rp = record;
		for (;;) {
			if (bp >= b_end) {
				size_t n;

				n = fread(buf, 1, sizeof(buf), pfp);
				if (n == 0) {
					if (ferror(pfp))
						goto done;
					(void)fclose(pfp);
					pfp = NULL;
					if (*++dbp == NULL) {
						status = 0;
						goto done;
					} else if ((pfp =
					    fopen(*dbp, "re")) == NULL) {
						goto done;
					} else
						continue;
				}
				b_end = buf + n;
				bp = buf;
			}

			c = *bp++;
			if (c == '\n') {
				if (rp > record && *(rp-1) == '\\') {
					rp--;
					continue;
				} else
					break;
			}
			*rp++ = c;

			/*
			 * Enforce loop invariant: if no room
			 * left in record buffer, try to get
			 * some more.
			 */
			if (rp >= r_end) {
				size_t newsize, off;
				char *nrecord;

				off = rp - record;
				newsize = r_end - record + BFRAG;
				nrecord = realloc(record, newsize);
				if (nrecord == NULL)
					goto done;
				record = nrecord;
				r_end = record + newsize;
				rp = record + off;
			}
		}
		/* loop invariant lets us do this */
		*rp++ = '\0';

		/*
		 * If not blank or comment, set toprec and topreclen so
		 * getent() doesn't have to re-parse the file to find it.
		 */
		if (*record != '\0' && *record != '#') {
			/* Rewind to end of record */
			fseeko(pfp, bp - b_end, SEEK_CUR);
			toprec = record;
			topreclen = rp - record;
			break;
		}
	}
lookup:
	/* extract name from record */
	len = strcspn(record, "|:");
	memcpy(nbuf, record, len);
	nbuf[len] = '\0';

	/* return value of getent() is one less than cgetnext() */
	pos = ftello(pfp);
	status = getent(cap, &dummy, dbp, pfp, nbuf, 0, NULL) + 1;
	if (status > 0)
		fseeko(pfp, pos, SEEK_SET);
done:
	serrno = errno;
	if (toprec != otoprec) {
		toprec = otoprec;
		topreclen = otopreclen;
		free(record);
	}
	if (status <= 0)
		(void)cgetclose();
	errno = serrno;

	return (status);
}
コード例 #4
0
ファイル: getcap.c プロジェクト: AhmadTux/freebsd
/*
 * Cgetnext() gets either the first or next entry in the logical database
 * specified by db_array.  It returns 0 upon completion of the database, 1
 * upon returning an entry with more remaining, and -1 if an error occurs.
 */
int
cgetnext(char **bp, char **db_array)
{
	size_t len;
	int done, hadreaderr, savederrno, status;
	char *cp, *line, *rp, *np, buf[BSIZE], nbuf[BSIZE];
	u_int dummy;

	if (dbp == NULL)
		dbp = db_array;

	if (pfp == NULL && (pfp = fopen(*dbp, "r")) == NULL) {
		(void)cgetclose();
		return (-1);
	}
	for (;;) {
		if (toprec && !gottoprec) {
			gottoprec = 1;
			line = toprec;
		} else {
			line = fgetln(pfp, &len);
			if (line == NULL && pfp) {
				hadreaderr = ferror(pfp);
				if (hadreaderr)
					savederrno = errno;
				fclose(pfp);
				pfp = NULL;
				if (hadreaderr) {
					cgetclose();
					errno = savederrno;
					return (-1);
				} else {
					if (*++dbp == NULL) {
						(void)cgetclose();
						return (0);
					} else if ((pfp =
					    fopen(*dbp, "r")) == NULL) {
						(void)cgetclose();
						return (-1);
					} else
						continue;
				}
			} else
				line[len - 1] = '\0';
			if (len == 1) {
				slash = 0;
				continue;
			}
			if (isspace((unsigned char)*line) ||
			    *line == ':' || *line == '#' || slash) {
				if (line[len - 2] == '\\')
					slash = 1;
				else
					slash = 0;
				continue;
			}
			if (line[len - 2] == '\\')
				slash = 1;
			else
				slash = 0;
		}


		/*
		 * Line points to a name line.
		 */
		done = 0;
		np = nbuf;
		for (;;) {
			for (cp = line; *cp != '\0'; cp++) {
				if (*cp == ':') {
					*np++ = ':';
					done = 1;
					break;
				}
				if (*cp == '\\')
					break;
				*np++ = *cp;
			}
			if (done) {
				*np = '\0';
				break;
			} else { /* name field extends beyond the line */
				line = fgetln(pfp, &len);
				if (line == NULL && pfp) {
					/* Name extends beyond the EOF! */
					hadreaderr = ferror(pfp);
					if (hadreaderr)
						savederrno = errno;
					fclose(pfp);
					pfp = NULL;
					if (hadreaderr) {
						cgetclose();
						errno = savederrno;
						return (-1);
					} else {
						cgetclose();
						return (-1);
					}
				} else
					line[len - 1] = '\0';
			}
		}
		rp = buf;
		for(cp = nbuf; *cp != '\0'; cp++)
			if (*cp == '|' || *cp == ':')
				break;
			else
				*rp++ = *cp;

		*rp = '\0';
		/*
		 * XXX
		 * Last argument of getent here should be nbuf if we want true
		 * sequential access in the case of duplicates.
		 * With NULL, getent will return the first entry found
		 * rather than the duplicate entry record.  This is a
		 * matter of semantics that should be resolved.
		 */
		status = getent(bp, &dummy, db_array, -1, buf, 0, NULL);
		if (status == -2 || status == -3)
			(void)cgetclose();

		return (status + 1);
	}
	/* NOTREACHED */
}
コード例 #5
0
ファイル: toe.c プロジェクト: AaronDP/ncurses-5.9_adbshell
static int
typelist(int eargc, char *eargv[],
	 bool verbosity,
	 void (*hook) (const char *, TERMTYPE *tp))
/* apply a function to each entry in given terminfo directories */
{
    int i;

    for (i = 0; i < eargc; i++) {
#if USE_DATABASE
	if (_nc_is_dir_path(eargv[i])) {
	    char *cwd_buf = 0;
	    DIR *termdir;
	    DIRENT *subdir;

	    if ((termdir = opendir(eargv[i])) == 0) {
		(void) fflush(stdout);
		(void) fprintf(stderr,
			       "%s: can't open terminfo directory %s\n",
			       _nc_progname, eargv[i]);
		return (EXIT_FAILURE);
	    } else if (verbosity)
		(void) printf("#\n#%s:\n#\n", eargv[i]);

	    while ((subdir = readdir(termdir)) != 0) {
		size_t len = NAMLEN(subdir);
		size_t cwd_len = len + strlen(eargv[i]) + 3;
		char name_1[PATH_MAX];
		DIR *entrydir;
		DIRENT *entry;

		cwd_buf = typeRealloc(char, cwd_len, cwd_buf);
		if (cwd_buf == 0)
		    failed("realloc cwd_buf");

		assert(cwd_buf != 0);

		strncpy(name_1, subdir->d_name, len)[len] = '\0';
		if (isDotname(name_1))
		    continue;

		(void) sprintf(cwd_buf, "%s/%.*s/", eargv[i], (int) len, name_1);
		if (chdir(cwd_buf) != 0)
		    continue;

		entrydir = opendir(".");
		if (entrydir == 0) {
		    perror(cwd_buf);
		    continue;
		}
		while ((entry = readdir(entrydir)) != 0) {
		    char name_2[PATH_MAX];
		    TERMTYPE lterm;
		    char *cn;
		    int status;

		    len = NAMLEN(entry);
		    strncpy(name_2, entry->d_name, len)[len] = '\0';
		    if (isDotname(name_2) || !_nc_is_file_path(name_2))
			continue;

		    status = _nc_read_file_entry(name_2, &lterm);
		    if (status <= 0) {
			(void) fflush(stdout);
			(void) fprintf(stderr,
				       "%s: couldn't open terminfo file %s.\n",
				       _nc_progname, name_2);
			return (EXIT_FAILURE);
		    }

		    /* only visit things once, by primary name */
		    cn = _nc_first_name(lterm.term_names);
		    if (!strcmp(cn, name_2)) {
			/* apply the selected hook function */
			(*hook) (cn, &lterm);
		    }
		    _nc_free_termtype(&lterm);
		}
		closedir(entrydir);
	    }
	    closedir(termdir);
	    if (cwd_buf != 0)
		free(cwd_buf);
	}
#if USE_HASHED_DB
	else {
	    DB *capdbp;
	    char filename[PATH_MAX];

	    if (make_db_name(filename, eargv[i], sizeof(filename))) {
		if ((capdbp = _nc_db_open(filename, FALSE)) != 0) {
		    DBT key, data;
		    int code;

		    code = _nc_db_first(capdbp, &key, &data);
		    while (code == 0) {
			TERMTYPE lterm;
			int used;
			char *have;
			char *cn;

			if (_nc_db_have_data(&key, &data, &have, &used)) {
			    if (_nc_read_termtype(&lterm, have, used) > 0) {
				/* only visit things once, by primary name */
				cn = _nc_first_name(lterm.term_names);
				/* apply the selected hook function */
				(*hook) (cn, &lterm);
				_nc_free_termtype(&lterm);
			    }
			}
			code = _nc_db_next(capdbp, &key, &data);
		    }

		    _nc_db_close(capdbp);
		}
	    }
	}
#endif
#endif
#if USE_TERMCAP
#if HAVE_BSD_CGETENT
	char *db_array[2];
	char *buffer = 0;

	if (verbosity)
	    (void) printf("#\n#%s:\n#\n", eargv[i]);

	db_array[0] = eargv[i];
	db_array[1] = 0;

	if (cgetfirst(&buffer, db_array)) {
	    show_termcap(buffer, hook);
	    free(buffer);
	    while (cgetnext(&buffer, db_array)) {
		show_termcap(buffer, hook);
		free(buffer);
	    }
	}
	cgetclose();
#else
	/* scan termcap text-file only */
	if (_nc_is_file_path(eargv[i])) {
	    char buffer[2048];
	    FILE *fp;

	    if ((fp = fopen(eargv[i], "r")) != 0) {
		while (fgets(buffer, sizeof(buffer), fp) != 0) {
		    if (*buffer == '#')
			continue;
		    if (isspace(*buffer))
			continue;
		    show_termcap(buffer, hook);
		}
		fclose(fp);
	    }
	}
#endif
#endif
    }