* Copyright (c) 1992 The Regents of the University of California.
* %sccs.include.redist.c%
"@(#) Copyright (c) 1992 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)cap_mkdb.c 1.6 (Berkeley) %G%";
static void db_build
__P((char **));
static void err
__P((int, const char *, ...));
static void getnamefield
__P((char **, char *));
static void usage
__P((void));
char *capdb
, **inputfiles
;
* 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:")) != EOF
) {
#define CAPDBNAMEEXTLEN 3 /* ".db" */
if ((capdb
= malloc(strlen(outname
) + CAPDBNAMEEXTLEN
+ 1)) == NULL
)
err(1, "%s", strerror(errno
));
(void)sprintf(capdb
, "%s.db", outname
);
* Any changes to these definitions should be made also in the getcap(3)
#define NBUFSIZ (8 * 1024)
* Db_build() builds the name and capabilty databases according to the
char *cp
, *np
, *bp
, *nf
, namebuf
[NBUFSIZ
];
if ((capdbp
= dbopen(capdb
, O_CREAT
| O_TRUNC
| O_WRONLY
,
DEFFILEMODE
, DB_HASH
, NULL
)) == NULL
)
err(1, "%s: %s", capdb
, strerror(errno
));
while((st
= cgetnext(&bp
, inputfiles
)) > 0) {
if ((bplen
= strlen(bp
)) > lastlen
) {
realloc(data
.data
, bplen
+ 2)) == NULL
)
err(1, "%s", strerror(errno
));
* Store record under name field.
((char *)(data
.data
))[0] = TCERR
;
((char *)(data
.data
))[0] = RECOK
;
(void)strcpy(&((char *)(data
.data
))[1], bp
);
key
.size
= strlen(nf
) + 1;
if ((stdb
= capdbp
->put(capdbp
, &key
, &data
, R_NOOVERWRITE
))
err(1, "put: %s", strerror(errno
));
err(0, "put: record '%s' already exists -- only first reference is stored", nf
);
printf("Hashed %d capability records.\r", i
++);
* Store references for other names.
(void)strcpy((char *)(data
.data
), nf
);
data
.size
= key
.size
+ 1; /* need extra byte for tag */
for (cp
= nf
; *cp
!= '\0'; cp
++) {
if (*cp
== ':' || *cp
== '|') {
key
.size
= strlen(namebuf
) + 1;
capdbp
->put(capdbp
, &key
, &data
,
err(1, "put: %s", strerror(errno
));
err(0, "put: record '%s' already exists -- only first reference is stored.",
if (capdbp
->close(capdbp
) < 0)
err(1, "%s", strerror(errno
));
err(1, "%s", strerror(errno
));
err(1, "potential reference loop detected");
for (cp
= bp
; *cp
!= ':'; cp
++);
if ((newsize
= cp
- bp
+ 1) > nfsize
) {
if ((*nf
= realloc(*nf
, newsize
)) == NULL
)
err(1, "%s", strerror(errno
));
"usage: cap_mkdb [-f outfile] file1 [file2 ...]\n");
err(int fatal
, const char *fmt
, ...)
(void)fprintf(stderr
, "\n");
(void)fprintf(stderr
, "cap_mkdb: ");
(void)vfprintf(stderr
, fmt
, ap
);
(void)fprintf(stderr
, "\n");