[BACK]Return to cap_mkdb.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / cap_mkdb

Annotation of src/usr.bin/cap_mkdb/cap_mkdb.c, Revision 1.1

1.1     ! deraadt     1: /*     $NetBSD: cap_mkdb.c,v 1.5 1995/09/02 05:47:12 jtc Exp $ */
        !             2:
        !             3: /*-
        !             4:  * Copyright (c) 1992, 1993
        !             5:  *     The Regents of the University of California.  All rights reserved.
        !             6:  *
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer in the
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  * 3. All advertising materials mentioning features or use of this software
        !            16:  *    must display the following acknowledgement:
        !            17:  *     This product includes software developed by the University of
        !            18:  *     California, Berkeley and its contributors.
        !            19:  * 4. Neither the name of the University nor the names of its contributors
        !            20:  *    may be used to endorse or promote products derived from this software
        !            21:  *    without specific prior written permission.
        !            22:  *
        !            23:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            24:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            25:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            26:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            27:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            28:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            29:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            31:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            32:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            33:  * SUCH DAMAGE.
        !            34:  */
        !            35:
        !            36: #ifndef lint
        !            37: static char copyright[] =
        !            38: "@(#) Copyright (c) 1992, 1993\n\
        !            39:        The Regents of the University of California.  All rights reserved.\n";
        !            40: #endif /* not lint */
        !            41:
        !            42: #ifndef lint
        !            43: #if 0
        !            44: static char sccsid[] = "@(#)cap_mkdb.c 8.2 (Berkeley) 4/27/95";
        !            45: #endif
        !            46: static char rcsid[] = "$NetBSD: cap_mkdb.c,v 1.5 1995/09/02 05:47:12 jtc Exp $";
        !            47: #endif /* not lint */
        !            48:
        !            49: #include <sys/param.h>
        !            50: #include <sys/stat.h>
        !            51:
        !            52: #include <db.h>
        !            53: #include <err.h>
        !            54: #include <errno.h>
        !            55: #include <fcntl.h>
        !            56: #include <limits.h>
        !            57: #include <stdio.h>
        !            58: #include <stdlib.h>
        !            59: #include <string.h>
        !            60: #include <unistd.h>
        !            61:
        !            62: void    db_build __P((char **));
        !            63: void    dounlink __P((void));
        !            64: void    usage __P((void));
        !            65:
        !            66: DB *capdbp;
        !            67: int verbose;
        !            68: char *capdb, *capname, buf[8 * 1024];
        !            69:
        !            70: HASHINFO openinfo = {
        !            71:        4096,           /* bsize */
        !            72:        16,             /* ffactor */
        !            73:        256,            /* nelem */
        !            74:        2048 * 1024,    /* cachesize */
        !            75:        NULL,           /* hash() */
        !            76:        0               /* lorder */
        !            77: };
        !            78:
        !            79: /*
        !            80:  * Mkcapdb creates a capability hash database for quick retrieval of capability
        !            81:  * records.  The database contains 2 types of entries: records and references
        !            82:  * marked by the first byte in the data.  A record entry contains the actual
        !            83:  * capability record whereas a reference contains the name (key) under which
        !            84:  * the correct record is stored.
        !            85:  */
        !            86: int
        !            87: main(argc, argv)
        !            88:        int argc;
        !            89:        char *argv[];
        !            90: {
        !            91:        int c;
        !            92:
        !            93:        capname = NULL;
        !            94:        while ((c = getopt(argc, argv, "f:v")) != EOF) {
        !            95:                switch(c) {
        !            96:                case 'f':
        !            97:                        capname = optarg;
        !            98:                        break;
        !            99:                case 'v':
        !           100:                        verbose = 1;
        !           101:                        break;
        !           102:                case '?':
        !           103:                default:
        !           104:                        usage();
        !           105:                }
        !           106:        }
        !           107:        argc -= optind;
        !           108:        argv += optind;
        !           109:
        !           110:        if (*argv == NULL)
        !           111:                usage();
        !           112:
        !           113:        /*
        !           114:         * The database file is the first argument if no name is specified.
        !           115:         * Make arrangements to unlink it if exit badly.
        !           116:         */
        !           117:        (void)snprintf(buf, sizeof(buf), "%s.db", capname ? capname : *argv);
        !           118:        if ((capname = strdup(buf)) == NULL)
        !           119:                err(1, "");
        !           120:        if ((capdbp = dbopen(capname, O_CREAT | O_TRUNC | O_RDWR,
        !           121:            DEFFILEMODE, DB_HASH, &openinfo)) == NULL)
        !           122:                err(1, "%s", buf);
        !           123:
        !           124:        if (atexit(dounlink))
        !           125:                err(1, "atexit");
        !           126:
        !           127:        db_build(argv);
        !           128:
        !           129:        if (capdbp->close(capdbp) < 0)
        !           130:                err(1, "%s", capname);
        !           131:        capname = NULL;
        !           132:        exit(0);
        !           133: }
        !           134:
        !           135: void
        !           136: dounlink()
        !           137: {
        !           138:        if (capname != NULL)
        !           139:                (void)unlink(capname);
        !           140: }
        !           141:
        !           142: /*
        !           143:  * Any changes to these definitions should be made also in the getcap(3)
        !           144:  * library routines.
        !           145:  */
        !           146: #define RECOK  (char)0
        !           147: #define TCERR  (char)1
        !           148: #define SHADOW (char)2
        !           149:
        !           150: /*
        !           151:  * Db_build() builds the name and capabilty databases according to the
        !           152:  * details above.
        !           153:  */
        !           154: void
        !           155: db_build(ifiles)
        !           156:        char **ifiles;
        !           157: {
        !           158:        DBT key, data;
        !           159:        recno_t reccnt;
        !           160:        size_t len, bplen;
        !           161:        int st;
        !           162:        char *bp, *p, *t;
        !           163:
        !           164:        data.data = NULL;
        !           165:        key.data = NULL;
        !           166:        for (reccnt = 0, bplen = 0; (st = cgetnext(&bp, ifiles)) > 0;) {
        !           167:
        !           168:                /*
        !           169:                 * Allocate enough memory to store record, terminating
        !           170:                 * NULL and one extra byte.
        !           171:                 */
        !           172:                len = strlen(bp);
        !           173:                if (bplen <= len + 2) {
        !           174:                        bplen += MAX(256, len + 2);
        !           175:                        if ((data.data = realloc(data.data, bplen)) == NULL)
        !           176:                                err(1, "");
        !           177:                }
        !           178:
        !           179:                /* Find the end of the name field. */
        !           180:                if ((p = strchr(bp, ':')) == NULL) {
        !           181:                        warnx("no name field: %.*s", MIN(len, 20), bp);
        !           182:                        continue;
        !           183:                }
        !           184:
        !           185:                /* First byte of stored record indicates status. */
        !           186:                switch(st) {
        !           187:                case 1:
        !           188:                        ((char *)(data.data))[0] = RECOK;
        !           189:                        break;
        !           190:                case 2:
        !           191:                        ((char *)(data.data))[0] = TCERR;
        !           192:                        warnx("Record not tc expanded: %.*s", p - bp, bp);
        !           193:                        break;
        !           194:                }
        !           195:
        !           196:                /* Create the stored record. */
        !           197:                memmove(&((u_char *)(data.data))[1], bp, len + 1);
        !           198:                data.size = len + 2;
        !           199:
        !           200:                /* Store the record under the name field. */
        !           201:                key.data = bp;
        !           202:                key.size = p - bp;
        !           203:
        !           204:                switch(capdbp->put(capdbp, &key, &data, R_NOOVERWRITE)) {
        !           205:                case -1:
        !           206:                        err(1, "put");
        !           207:                        /* NOTREACHED */
        !           208:                case 1:
        !           209:                        warnx("ignored duplicate: %.*s",
        !           210:                            key.size, (char *)key.data);
        !           211:                        continue;
        !           212:                }
        !           213:                ++reccnt;
        !           214:
        !           215:                /* If only one name, ignore the rest. */
        !           216:                if ((p = strchr(bp, '|')) == NULL)
        !           217:                        continue;
        !           218:
        !           219:                /* The rest of the names reference the entire name. */
        !           220:                ((char *)(data.data))[0] = SHADOW;
        !           221:                memmove(&((u_char *)(data.data))[1], key.data, key.size);
        !           222:                data.size = key.size + 1;
        !           223:
        !           224:                /* Store references for other names. */
        !           225:                for (p = t = bp;; ++p) {
        !           226:                        if (p > t && (*p == ':' || *p == '|')) {
        !           227:                                key.size = p - t;
        !           228:                                key.data = t;
        !           229:                                switch(capdbp->put(capdbp,
        !           230:                                    &key, &data, R_NOOVERWRITE)) {
        !           231:                                case -1:
        !           232:                                        err(1, "put");
        !           233:                                        /* NOTREACHED */
        !           234:                                case 1:
        !           235:                                        warnx("ignored duplicate: %.*s",
        !           236:                                            key.size, (char *)key.data);
        !           237:                                }
        !           238:                                t = p + 1;
        !           239:                        }
        !           240:                        if (*p == ':')
        !           241:                                break;
        !           242:                }
        !           243:        }
        !           244:
        !           245:        switch(st) {
        !           246:        case -1:
        !           247:                err(1, "file argument");
        !           248:                /* NOTREACHED */
        !           249:        case -2:
        !           250:                errx(1, "potential reference loop detected");
        !           251:                /* NOTREACHED */
        !           252:        }
        !           253:
        !           254:        if (verbose)
        !           255:                (void)printf("cap_mkdb: %d capability records\n", reccnt);
        !           256: }
        !           257:
        !           258: void
        !           259: usage()
        !           260: {
        !           261:        (void)fprintf(stderr,
        !           262:            "usage: cap_mkdb [-v] [-f outfile] file1 [file2 ...]\n");
        !           263:        exit(1);
        !           264: }