diff options
Diffstat (limited to 'usr.bin/cap_mkdb')
-rw-r--r-- | usr.bin/cap_mkdb/Makefile | 4 | ||||
-rw-r--r-- | usr.bin/cap_mkdb/cap_mkdb.1 | 25 | ||||
-rw-r--r-- | usr.bin/cap_mkdb/cap_mkdb.c | 110 | ||||
-rw-r--r-- | usr.bin/cap_mkdb/getinfo.c | 675 |
4 files changed, 38 insertions, 776 deletions
diff --git a/usr.bin/cap_mkdb/Makefile b/usr.bin/cap_mkdb/Makefile index 55b86c5c7f8..63ce2f5b974 100644 --- a/usr.bin/cap_mkdb/Makefile +++ b/usr.bin/cap_mkdb/Makefile @@ -1,6 +1,6 @@ -# $OpenBSD: Makefile,v 1.4 1999/03/05 04:47:45 tholo Exp $ +# $OpenBSD: Makefile,v 1.5 2015/12/04 13:58:09 nicm Exp $ PROG= cap_mkdb -SRCS= cap_mkdb.c getinfo.c +SRCS= cap_mkdb.c .include <bsd.prog.mk> diff --git a/usr.bin/cap_mkdb/cap_mkdb.1 b/usr.bin/cap_mkdb/cap_mkdb.1 index 796a0c6f0e0..36861c8f85e 100644 --- a/usr.bin/cap_mkdb/cap_mkdb.1 +++ b/usr.bin/cap_mkdb/cap_mkdb.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: cap_mkdb.1,v 1.18 2015/12/03 11:32:34 nicm Exp $ +.\" $OpenBSD: cap_mkdb.1,v 1.19 2015/12/04 13:58:09 nicm Exp $ .\" $NetBSD: cap_mkdb.1,v 1.4 1995/03/26 03:59:36 glass Exp $ .\" .\" Copyright (c) 1992, 1993 @@ -30,7 +30,7 @@ .\" .\" @(#)cap_mkdb.1 8.1 (Berkeley) 6/6/93 .\" -.Dd $Mdocdate: December 3 2015 $ +.Dd $Mdocdate: December 4 2015 $ .Dt CAP_MKDB 1 .Os .Sh NAME @@ -46,8 +46,6 @@ .Nm builds a hashed database out of the .Xr getcap 3 -or -.Xr terminfo 5 logical database constructed by the concatenation of the specified files. .Pp @@ -68,10 +66,6 @@ The options are as follows: .Bl -tag -width Ds .It Fl f Ar outfile Specify a different database basename. -.It Fl i -Expect the capability records to be parsed to be in -.Xr terminfo 5 -format. .It Fl v Print out the number of capability records in the database. .El @@ -99,22 +93,9 @@ in a key/data pair of the second type. The data field of this key/data pair is used to look up a key/data pair of the first type which has the real data associated with the name. -.Sh FILES -.Bl -tag -width /usr/share/misc/termcap.db -compact -.It Pa /usr/share/misc/termcap -uncompiled terminal capabilities file -.It Pa /usr/share/misc/termcap.db -terminal capabilities database -.It Pa /usr/share/terminfo -terminal information database -.It Pa /etc/termcap -symbolic link to -.Pa /usr/share/misc/termcap -.El .Sh EXIT STATUS .Ex -std cap_mkdb .Sh SEE ALSO .Xr dbopen 3 , .Xr getcap 3 , -.Xr termcap 5 , -.Xr terminfo 5 +.Xr termcap 5 diff --git a/usr.bin/cap_mkdb/cap_mkdb.c b/usr.bin/cap_mkdb/cap_mkdb.c index 7175d2603d6..4911a65ea7a 100644 --- a/usr.bin/cap_mkdb/cap_mkdb.c +++ b/usr.bin/cap_mkdb/cap_mkdb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cap_mkdb.c,v 1.20 2015/10/29 02:58:00 deraadt Exp $ */ +/* $OpenBSD: cap_mkdb.c,v 1.21 2015/12/04 13:58:09 nicm Exp $ */ /* $NetBSD: cap_mkdb.c,v 1.5 1995/09/02 05:47:12 jtc Exp $ */ /*- @@ -53,7 +53,7 @@ int igetnext(char **, char **); int main(int, char *[]); DB *capdbp; -int info, verbose; +int verbose; char *capname, buf[8 * 1024]; HASHINFO openinfo = { @@ -89,9 +89,6 @@ main(int argc, char *argv[]) case 'v': verbose = 1; break; - case 'i': - info = 1; - break; case '?': default: usage(); @@ -151,23 +148,21 @@ db_build(char **ifiles) recno_t reccnt; size_t len, bplen; int st; - char *bp, *p, *t, *out, ch; + char *bp, *p, *t, *capbeg, *capend; cgetusedb(0); /* disable reading of .db files in getcap(3) */ data.data = NULL; key.data = NULL; - for (reccnt = 0, bplen = 0; - (st = (info ? igetnext(&bp, ifiles) : cgetnext(&bp, ifiles))) > 0;) { + for (reccnt = 0, bplen = 0; (st = cgetnext(&bp, ifiles)) > 0;) { /* - * Allocate enough memory to store four times the size of the - * record (so an existing ':' can be expanded to '\072' for - * terminfo) plus a terminating NULL and one extra byte. + * Allocate enough memory to store the size of the record plus + * a terminating NULL and one extra byte. */ len = strlen(bp); - if (bplen <= 4 * len + 2) { - int newbplen = bplen + MAXIMUM(256, 4 * len + 2); + if (bplen <= len + 2) { + int newbplen = bplen + MAXIMUM(256, len + 2); void *newdata; if ((newdata = realloc(data.data, newbplen)) == NULL) @@ -177,7 +172,7 @@ db_build(char **ifiles) } /* Find the end of the name field. */ - if ((p = strchr(bp, info ? ',' : ':')) == NULL) { + if ((p = strchr(bp, ':')) == NULL) { warnx("no name field: %.*s", (int)MINIMUM(len, 20), bp); continue; } @@ -194,70 +189,31 @@ db_build(char **ifiles) } /* Create the stored record. */ - if (info) { - /* - * The record separator is :, so it is necessary to - * change commas into colons. However, \, should be - * left alone, unless the \ is the last part of ^\. - */ - data.size = len + 2; - out = ((char *) data.data) + 1; - t = bp; - while (t < bp + len) { - switch (ch = *t++) { - case '^': - case '\\': - *out++ = ch; - if (*t != '\0') - *out++ = *t++; - break; - case ':': - memcpy(out, "\\072", 4); - out += 4; - data.size += 3; /* : already counted */ - break; - case ',': - *out++ = ':'; - break; - default: - *out++ = ch; - break; - } - } - *out++ = '\0'; - if (memchr((char *)data.data + 1, '\0', data.size - 2)) { - warnx("NUL in entry: %.*s", (int)MINIMUM(len, 20), bp); - continue; - } - } else { - char *capbeg, *capend; + t = (char *)data.data + 1; + /* Copy the cap name and trailing ':' */ + len = p - bp + 1; + memcpy(t, bp, len); + t += len; + + /* Copy entry, collapsing empty fields. */ + capbeg = p + 1; + while (*capbeg) { + /* Skip empty fields. */ + if ((len = strspn(capbeg, ": \t\n\r"))) + capbeg += len; - t = (char *)data.data + 1; - /* Copy the cap name and trailing ':' */ - len = p - bp + 1; - memcpy(t, bp, len); + /* Find the end of this cap and copy it w/ : */ + capend = strchr(capbeg, ':'); + if (capend) + len = capend - capbeg + 1; + else + len = strlen(capbeg); + memcpy(t, capbeg, len); t += len; - - /* Copy entry, collapsing empty fields. */ - capbeg = p + 1; - while (*capbeg) { - /* Skip empty fields. */ - if ((len = strspn(capbeg, ": \t\n\r"))) - capbeg += len; - - /* Find the end of this cap and copy it w/ : */ - capend = strchr(capbeg, ':'); - if (capend) - len = capend - capbeg + 1; - else - len = strlen(capbeg); - memcpy(t, capbeg, len); - t += len; - capbeg += len; - } - *t = '\0'; - data.size = t - (char *)data.data + 1; + capbeg += len; } + *t = '\0'; + data.size = t - (char *)data.data + 1; /* Store the record under the name field. */ key.data = bp; @@ -285,7 +241,7 @@ db_build(char **ifiles) /* Store references for other names. */ for (p = t = bp;; ++p) { - if (p > t && (*p == (info ? ',' : ':') || *p == '|')) { + if (p > t && (*p == ':' || *p == '|')) { key.size = p - t; key.data = t; @@ -309,7 +265,7 @@ db_build(char **ifiles) } t = p + 1; } - if (*p == (info ? ',' : ':')) + if (*p == ':') break; } free(bp); diff --git a/usr.bin/cap_mkdb/getinfo.c b/usr.bin/cap_mkdb/getinfo.c deleted file mode 100644 index 228cb448afc..00000000000 --- a/usr.bin/cap_mkdb/getinfo.c +++ /dev/null @@ -1,675 +0,0 @@ -/* $OpenBSD: getinfo.c,v 1.19 2013/11/26 18:47:06 deraadt Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. - * Copyright (c) 1996 SigmaSoft, Th. Lockert <tholo@sigmasoft.com> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/types.h> - -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#define BFRAG 1024 -#define BSIZE 1024 -#define ESC ('[' & 037) /* ASCII ESC */ -#define MAX_RECURSION 32 /* maximum getent recursion */ -#define SFRAG 100 /* cgetstr mallocs in SFRAG chunks */ - -#define RECOK (char)0 -#define TCERR (char)1 -#define SHADOW (char)2 - -static int getent(char **, u_int *, char **, FILE *, char *, int); -static char *igetcap(char *, char *, int); -static int igetmatch(char *, char *); -static int igetclose(void); - -int igetnext(char **, char **); - -/* - * Igetcap searches the capability record buf for the capability cap with - * type `type'. A pointer to the value of cap is returned on success, NULL - * if the requested capability couldn't be found. - * - * Specifying a type of ',' means that nothing should follow cap (,cap,). - * In this case a pointer to the terminating ',' or NUL will be returned if - * cap is found. - * - * If (cap, '@') or (cap, terminator, '@') is found before (cap, terminator) - * return NULL. - */ -static char * -igetcap(char *buf, char *cap, int type) -{ - char *bp, *cp; - - bp = buf; - for (;;) { - /* - * Skip past the current capability field - it's either the - * name field if this is the first time through the loop, or - * the remainder of a field whose name failed to match cap. - */ - for (;;) - if (*bp == '\0') - return (NULL); - else - if (*bp++ == ',') - break; - - /* - * Try to match (cap, type) in buf. - */ - for (cp = cap; *cp == *bp && *bp != '\0'; cp++, bp++) - continue; - if (*cp != '\0') - continue; - if (*bp == '@') - return (NULL); - if (type == ',') { - if (*bp != '\0' && *bp != ',') - continue; - return(bp); - } - if (*bp != type) - continue; - bp++; - return (*bp == '@' ? NULL : bp); - } - /* NOTREACHED */ -} - -/* - * Getent implements the functions of igetent. If fp is non-NULL, - * *db_array has already been opened and fp is the open file descriptor. We - * do this to save time and avoid using up file descriptors for use= - * recursions. - * - * Getent returns the same success/failure codes as igetent. On success, a - * pointer to a malloc'ed capability record with all use= capabilities fully - * expanded and its length (not including trailing ASCII NUL) are left in - * *cap and *len. - * - * Basic algorithm: - * + Allocate memory incrementally as needed in chunks of size BFRAG - * for capability buffer. - * + Recurse for each use=name and interpolate result. Stop when all - * names interpolated, a name can't be found, or depth exceeds - * MAX_RECURSION. - */ -static int -getent(char **cap, u_int *len, char **db_array, FILE *fp, char *name, int depth) -{ - char *r_end, *rp, **db_p; - int myfd, eof, foundit; - char *record, *s; - int tc_not_resolved; - - /* - * Return with ``loop detected'' error if we've recursed more than - * MAX_RECURSION times. - */ - if (depth > MAX_RECURSION) - return (-3); - - /* - * If no name we better have a record in cap - */ - if (depth == 0 && name == NULL) { - if ((record = malloc(*len + 1 + BFRAG)) == NULL) - return (-2); - memcpy(record, *cap, *len); - myfd = 0; - db_p = db_array; - rp = record + *len + 1; - r_end = rp + BFRAG; - *rp = '\0'; - goto exp_use; - } - - /* - * Allocate first chunk of memory. - */ - if ((record = malloc(BFRAG)) == NULL) { - errno = ENOMEM; - return (-2); - } - r_end = record + BFRAG; - foundit = 0; - rp = NULL; - myfd = -1; - - /* - * Loop through database array until finding the record. - */ - for (db_p = db_array; *db_p != NULL; db_p++) { - eof = 0; - - /* - * Open database if not already open. - */ - - if (fp != NULL) { - (void)fseek(fp, 0L, SEEK_SET); - myfd = 0; - } else { - fp = fopen(*db_p, "r"); - if (fp == NULL) { - /* No error on unfound file. */ - continue; - } - myfd = 1; - } - /* - * Find the requested capability record ... - */ - { - char buf[BUFSIZ]; - char *b_end, *bp; - int c; - - /* - * 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 record implementing line continuation. - */ - rp = record; - for (;;) { - if (bp >= b_end) { - size_t n; - - n = fread(buf, 1, sizeof(buf), fp); - if (n == 0) { - eof = feof(fp); - if (myfd) - (void)fclose(fp); - if (eof) { - fp = NULL; - break; - } - free(record); - return (-2); - } - b_end = buf+n; - bp = buf; - } - - c = (unsigned char)*bp++; - if (c == '\n') { - if (bp >= b_end) { - size_t n; - - n = fread(buf, 1, sizeof(buf), fp); - if (n == 0) { - eof = feof(fp); - if (myfd) - (void)fclose(fp); - if (eof) { - fp = NULL; - break; - } - free(record); - return (-2); - } - b_end = buf+n; - bp = buf; - } - if (rp > record && isspace(*bp)) - continue; - else - break; - } - if (rp <= record || *(rp - 1) != ',' || !isspace(c)) - *rp++ = c; - - /* - * Enforce loop invariant: if no room - * left in record buffer, try to get - * some more. - */ - if (rp >= r_end) { - size_t off; - size_t newsize; - - off = rp - record; - newsize = r_end - record + BFRAG; - s = realloc(record, newsize); - if (s == NULL) { - free(record); - errno = ENOMEM; - if (myfd) - (void)fclose(fp); - return (-2); - } - record = s; - r_end = record + newsize; - rp = record + off; - } - } - /* loop invariant lets us do this */ - *rp++ = '\0'; - - /* - * Toss blank lines and comments. - */ - if (*record == '\0' || *record == '#') - continue; - - /* - * See if this is the record we want ... - */ - if (igetmatch(record, name) == 0) { - foundit = 1; - break; /* found it! */ - } - - /* - * If encountered eof check next file. - */ - if (eof) - break; - } - } - if (foundit) - break; - } - - if (!foundit) { - free(record); - return (-1); - } - - /* - * Got the capability record, but now we have to expand all use=name - * references in it ... - */ -exp_use: { - char *newicap; - int newilen; - u_int ilen; - int diff, iret, tclen; - char *icap, *scan, *tc, *tcstart, *tcend; - - /* - * Loop invariants: - * There is room for one more character in record. - * R_end points just past end of record. - * Rp points just past last character in record. - * Scan points at remainder of record that needs to be - * scanned for use=name constructs. - */ - scan = record; - tc_not_resolved = 0; - for (;;) { - if ((tc = igetcap(scan, "use", '=')) == NULL) - break; - - /* - * Find end of use=name and stomp on the trailing `,' - * (if present) so we can use it to call ourselves. - */ - s = tc + strcspn(tc, ","); - if (*s == ',') { - *s = '\0'; - ++s; - } - tcstart = tc - 4; - tclen = s - tcstart; - tcend = s; - - iret = getent(&icap, &ilen, db_p, fp, tc, depth+1); - newicap = icap; /* Put into a register. */ - newilen = ilen; - if (iret != 0) { - /* an error */ - if (iret < -1) { - if (myfd) - (void)fclose(fp); - free(record); - return (iret); - } - if (iret == 1) - tc_not_resolved = 1; - /* couldn't resolve tc */ - if (iret == -1) { - *(s - 1) = ','; - scan = s - 1; - tc_not_resolved = 1; - continue; - - } - } - /* not interested in name field of tc'ed record */ - s = newicap + strcspn(newicap, ","); - if (*s == ',') - ++s; - newilen -= s - newicap; - newicap = s; - - /* make sure interpolated record is `,'-terminated */ - s += newilen; - if (*(s-1) != ',') { - *s = ','; /* overwrite NUL with , */ - newilen++; - } - - /* - * Make sure there's enough room to insert the - * new record. - */ - diff = newilen - tclen; - if (diff >= r_end - rp) { - size_t off, tcoff, tcoffend; - size_t newsize; - - off = rp - record; - newsize = r_end - record + diff + BFRAG; - tcoff = tcstart - record; - tcoffend = tcend - record; - s = realloc(record, newsize); - if (s == NULL) { - free(record); - errno = ENOMEM; - if (myfd) - (void)fclose(fp); - free(icap); - return (-2); - } - record = s; - r_end = record + newsize; - rp = record + off; - tcstart = record + tcoff; - tcend = record + tcoffend; - } - - /* - * Insert tc'ed record into our record. - */ - s = tcstart + newilen; - bcopy(tcend, s, (size_t)(rp - tcend)); - bcopy(newicap, tcstart, (size_t)newilen); - rp += diff; - free(icap); - - /* - * Start scan on `,' so next igetcap works properly - * (igetcap always skips first field). - */ - scan = s-1; - } - - } - /* - * Close file (if we opened it), give back any extra memory, and - * return capability, length and success. - */ - if (myfd) - (void)fclose(fp); - *len = rp - record - 1; /* don't count NUL */ - if (r_end > rp) { - if ((s = - realloc(record, (size_t)(rp - record))) == NULL) { - free(record); - errno = ENOMEM; - return (-2); - } else - record = s; - } - - *cap = record; - if (tc_not_resolved) - return (1); - return (0); -} - -/* - * Igetmatch will return 0 if name is one of the names of the capability - * record buf, -1 if not. - */ -static int -igetmatch(char *buf, char *name) -{ - char *np, *bp; - - /* - * Start search at beginning of record. - */ - bp = buf; - for (;;) { - /* - * Try to match a record name. - */ - np = name; - for (;;) - if (*np == '\0') { - if (*bp == '|' || *bp == ',' || *bp == '\0') - return (0); - else - break; - } else { - if (*bp++ != *np++) - break; - } - - /* - * Match failed, skip to next name in record. - */ - bp--; /* a '|' or ',' may have stopped the match */ - for (;;) - if (*bp == '\0' || *bp == ',') - return (-1); /* match failed totally */ - else - if (*bp++ == '|') - break; /* found next name */ - } -} - -static FILE *pfp; -static int slash; -static char **dbp; - -static int -igetclose(void) -{ - if (pfp != NULL) { - (void)fclose(pfp); - pfp = NULL; - } - dbp = NULL; - slash = 0; - return(0); -} - -/* - * Igetnext() 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 -igetnext(char **cap, char **db_array) -{ - int c, eof = 0, serrno, status = -1; - char buf[BUFSIZ]; - char *b_end, *bp, *r_end, *rp; - char *record = NULL; - u_int len; - off_t pos; - - if (dbp == NULL) - dbp = db_array; - - if (pfp == NULL && (pfp = fopen(*dbp, "r")) == NULL) - goto done; - - /* - * 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 (;;) { - /* - * If encountered EOF check next file. - */ - if (eof) { - (void)fclose(pfp); - pfp = NULL; - if (*++dbp == NULL) { - status = 0; - break; - } - if ((pfp = fopen(*dbp, "r")) == NULL) - break; - eof = 0; - } - - /* - * Read in a record implementing line continuation. - */ - rp = record; - for (;;) { - if (bp >= b_end) { - size_t n; - - n = fread(buf, 1, sizeof(buf), pfp); - if (n == 0) { - eof = feof(pfp); - if (eof) - break; - else - goto done; - } - b_end = buf + n; - bp = buf; - } - - c = (unsigned char)*bp++; - if (c == '\n') { - if (bp >= b_end) { - size_t n; - - n = fread(buf, 1, sizeof(buf), pfp); - if (n == 0) { - eof = feof(pfp); - if (eof) - break; - else - goto done; - } - b_end = buf + n; - bp = buf; - } - if (rp > record && isspace(*bp)) - continue; - else - break; - } - if (rp <= record || *(rp - 1) != ',' || !isspace(c)) - *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'; - - /* - * Toss blank lines and comments. - */ - if (*record == '\0' || *record == '#') - continue; - - /* rewind to end of record */ - fseeko(pfp, (off_t)(bp - b_end), SEEK_CUR); - - /* we pass the record to getent() in cap */ - *cap = record; - len = rp - record; - - /* return value of getent() is one less than igetnext() */ - pos = ftello(pfp); - status = getent(cap, &len, dbp, pfp, NULL, 0) + 1; - if (status > 0) - fseeko(pfp, pos, SEEK_SET); - break; - } -done: - serrno = errno; - free(record); - if (status <= 0) - (void)igetclose(); - errno = serrno; - - return (status); -} |