* Copyright (c) 1992 The Regents of the University of California.
* %sccs.include.redist.c%
static char copyright
[] =
"@(#) Copyright (c) 1992 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)cap_mkdb.c 5.5 (Berkeley) %G%";
void db_build
__P((char **));
void dounlink
__P((void));
char *capdb
, *capname
, buf
[8 * 1024];
* Mkcapdb creates a capability hash database for quick retrieval of capability
* records. The database contains 2 types of entries: records and references
* marked by the first byte in the data. A record entry contains the actual
* capability record whereas a reference contains the name (key) under which
* the correct record is stored.
while ((c
= getopt(argc
, argv
, "f:v")) != EOF
) {
* The database file is the first argument if no name is specified.
* Make arrangements to unlink it if exit badly.
(void)snprintf(buf
, sizeof(buf
), "%s.db", capname
? capname
: *argv
);
if ((capname
= strdup(buf
)) == NULL
)
if ((capdbp
= dbopen(capname
,
O_CREAT
| O_TRUNC
| O_RDWR
, DEFFILEMODE
, DB_HASH
, NULL
)) == NULL
)
if (capdbp
->close(capdbp
) < 0)
* Any changes to these definitions should be made also in the getcap(3)
* Db_build() builds the name and capabilty databases according to the
for (reccnt
= 0, bplen
= 0; (st
= cgetnext(&bp
, ifiles
)) > 0;) {
* Allocate enough memory to store record, terminating
* NULL and one extra byte.
bplen
+= MAX(256, len
+ 2);
if ((data
.data
= realloc(data
.data
, bplen
)) == NULL
)
/* First byte of stored record indicates error. */
((char *)(data
.data
))[0] = st
== 2 ? TCERR
: RECOK
;
/* Create the stored record. */
memmove(&((u_char
*)(data
.data
))[1], bp
, len
+ 1);
/* Store record under name field. */
if ((p
= strchr(bp
, ':')) == NULL
) {
warn("no name field: %.*s", MIN(len
, 20), bp
);
switch(capdbp
->put(capdbp
, &key
, &data
, R_NOOVERWRITE
)) {
warnx("ignored duplicate: %.*s",
key
.size
, (char *)key
.data
);
/* If only one name, ignore the rest. */
if ((p
= strchr(bp
, '|')) == NULL
)
/* The rest of the names reference the entire name. */
((char *)(data
.data
))[0] = SHADOW
;
memmove(&((u_char
*)(data
.data
))[1], key
.data
, key
.size
);
data
.size
= key
.size
+ 1;
/* Store references for other names. */
if (p
> t
&& (*p
== ':' || *p
== '|')) {
switch(capdbp
->put(capdbp
,
&key
, &data
, R_NOOVERWRITE
)) {
warnx("ignored duplicate: %.*s",
key
.size
, (char *)key
.data
);
errx(1, "potential reference loop detected");
(void)printf("cap_mkdb: %d capability records\n", reccnt
);
"usage: cap_mkdb [-v] [-f outfile] file1 [file2 ...]\n");