int cgetfirst(char **buf, char **db_array) { (void)cgetclose(); return (cgetnext(buf, db_array)); }
void lastprinter(void) { cgetclose(); }
/* * 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); }
/* * 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 */ }
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, <erm); 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, <erm); } _nc_free_termtype(<erm); } 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(<erm, have, used) > 0) { /* only visit things once, by primary name */ cn = _nc_first_name(lterm.term_names); /* apply the selected hook function */ (*hook) (cn, <erm); _nc_free_termtype(<erm); } } 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 }