Commit | Line | Data |
---|---|---|
5a884762 | 1 | /*- |
06c161de EA |
2 | * Copyright (c) 1992 The Regents of the University of California. |
3 | * All rights reserved. | |
4 | * | |
5a884762 | 5 | * %sccs.include.redist.c% |
06c161de EA |
6 | */ |
7 | ||
8 | #ifndef lint | |
a40b35c0 | 9 | static char copyright[] = |
06c161de EA |
10 | "@(#) Copyright (c) 1992 The Regents of the University of California.\n\ |
11 | All rights reserved.\n"; | |
12 | #endif /* not lint */ | |
13 | ||
14 | #ifndef lint | |
4bf71922 | 15 | static char sccsid[] = "@(#)cap_mkdb.c 5.4 (Berkeley) %G%"; |
06c161de EA |
16 | #endif /* not lint */ |
17 | ||
415e0f84 | 18 | #include <sys/param.h> |
0825a747 | 19 | #include <sys/stat.h> |
5a884762 | 20 | |
06c161de | 21 | #include <db.h> |
5a884762 EA |
22 | #include <errno.h> |
23 | #include <fcntl.h> | |
24 | #include <limits.h> | |
06c161de EA |
25 | #include <stdio.h> |
26 | #include <stdlib.h> | |
27 | #include <string.h> | |
06c161de | 28 | #include <unistd.h> |
06c161de EA |
29 | |
30 | static void db_build __P((char **)); | |
4b9c212b | 31 | static void err __P((int, const char *, ...)); |
06c161de EA |
32 | static void getnamefield __P((char **, char *)); |
33 | static void usage __P((void)); | |
34 | ||
188c396b | 35 | int docapdbunlink, printnl, verbose; |
5a884762 | 36 | char *capdb, **inputfiles; |
06c161de EA |
37 | |
38 | /* | |
5a884762 EA |
39 | * Mkcapdb creates a capability hash database for quick retrieval of capability |
40 | * records. The database contains 2 types of entries: records and references | |
41 | * marked by the first byte in the data. A record entry contains the actual | |
42 | * capability record whereas a reference contains the name (key) under which | |
43 | * the correct record is stored. | |
06c161de | 44 | */ |
5a884762 | 45 | int |
06c161de EA |
46 | main(argc, argv) |
47 | int argc; | |
5a884762 | 48 | char *argv[]; |
06c161de | 49 | { |
415e0f84 EA |
50 | int c, fd; |
51 | char *outname, buf[MAXPATHLEN + 1], **f; | |
06c161de EA |
52 | |
53 | outname = NULL; | |
188c396b | 54 | while ((c = getopt(argc, argv, "f:v")) != EOF) { |
06c161de EA |
55 | switch(c) { |
56 | case 'f': | |
57 | outname = optarg; | |
58 | break; | |
188c396b KB |
59 | case 'v': |
60 | verbose = 1; | |
61 | break; | |
06c161de | 62 | case '?': |
5a884762 | 63 | default: |
06c161de EA |
64 | usage(); |
65 | } | |
0825a747 | 66 | } |
06c161de | 67 | argc -= optind; |
0825a747 KB |
68 | argv += optind; |
69 | ||
06c161de EA |
70 | if (*argv == NULL) |
71 | usage(); | |
72 | ||
73 | inputfiles = argv; | |
74 | ||
75 | if (outname == NULL) | |
76 | outname = *inputfiles; | |
77 | ||
5a884762 EA |
78 | #define CAPDBNAMEEXTLEN 3 /* ".db" */ |
79 | if ((capdb = malloc(strlen(outname) + CAPDBNAMEEXTLEN + 1)) == NULL) | |
4b9c212b | 80 | err(1, "%s", strerror(errno)); |
5a884762 | 81 | (void)sprintf(capdb, "%s.db", outname); |
06c161de | 82 | |
0825a747 KB |
83 | /* |
84 | * We want to avoid the confusion of where the capability record | |
85 | * is being read from. Since the user probably intends to read the | |
86 | * ascii file, we should make sure that user knows that the | |
415e0f84 | 87 | * corresponding .db file will override. |
0825a747 | 88 | */ |
415e0f84 EA |
89 | for (f = inputfiles; *f != NULL; f++) { |
90 | (void)sprintf(buf, "%s.db", *f); | |
188c396b | 91 | fd = open(buf, O_RDONLY, 0); |
0825a747 KB |
92 | if (fd == -1 && errno != ENOENT) |
93 | err(1, "%s: %s", buf, strerror(errno)); | |
415e0f84 | 94 | if (fd >= 0) { |
188c396b | 95 | err(0, "%s.db overrides %s.", *f, *f); |
415e0f84 EA |
96 | (void)close(fd); |
97 | } | |
98 | } | |
e8e9e2d0 | 99 | |
0825a747 | 100 | db_build(inputfiles); |
06c161de EA |
101 | exit(0); |
102 | } | |
0825a747 | 103 | |
06c161de EA |
104 | /* |
105 | * Any changes to these definitions should be made also in the getcap(3) | |
106 | * library routines. | |
107 | */ | |
a86ecba7 EA |
108 | |
109 | #define RECOK (char)0 | |
110 | #define TCERR (char)1 | |
111 | ||
5a884762 | 112 | #define NBUFSIZ (8 * 1024) |
06c161de EA |
113 | |
114 | /* | |
115 | * Db_build() builds the name and capabilty databases according to the | |
116 | * details above. | |
117 | */ | |
5a884762 | 118 | void |
06c161de EA |
119 | db_build(inputfiles) |
120 | char **inputfiles; | |
121 | { | |
122 | DB *capdbp; | |
123 | DBT key, data; | |
0825a747 | 124 | recno_t reccnt; |
06c161de | 125 | size_t lastlen, bplen; |
0825a747 | 126 | int st, stdb; |
5a884762 | 127 | char *cp, *np, *bp, *nf, namebuf[NBUFSIZ]; |
0825a747 KB |
128 | |
129 | if ((capdbp = dbopen(capdb, O_CREAT | O_TRUNC | O_RDWR, | |
130 | DEFFILEMODE, DB_HASH, NULL)) == NULL) | |
4b9c212b | 131 | err(1, "%s: %s", capdb, strerror(errno)); |
5a884762 | 132 | docapdbunlink = 1; |
0825a747 | 133 | |
06c161de | 134 | lastlen = 0; |
5a884762 EA |
135 | nf = NULL; |
136 | data.data = NULL; | |
137 | key.data = NULL; | |
0825a747 | 138 | for (reccnt = 0; (st = cgetnext(&bp, inputfiles)) > 0;) { |
06c161de EA |
139 | getnamefield(&nf, bp); |
140 | if ((bplen = strlen(bp)) > lastlen) { | |
0825a747 | 141 | if ((data.data = realloc(data.data, bplen + 2)) == NULL) |
4b9c212b | 142 | err(1, "%s", strerror(errno)); |
06c161de EA |
143 | lastlen = bplen; |
144 | } | |
145 | ||
0825a747 | 146 | /* Store record under name field. */ |
a86ecba7 EA |
147 | if (st == 2) |
148 | ((char *)(data.data))[0] = TCERR; | |
149 | else | |
150 | ((char *)(data.data))[0] = RECOK; | |
0825a747 | 151 | |
5a884762 | 152 | (void)strcpy(&((char *)(data.data))[1], bp); |
06c161de | 153 | data.size = bplen + 2; |
e41e2450 EA |
154 | key.data = nf; |
155 | key.size = strlen(nf) + 1; | |
0825a747 KB |
156 | if ((stdb = |
157 | capdbp->put(capdbp, &key, &data, R_NOOVERWRITE)) < 0) | |
4b9c212b EA |
158 | err(1, "put: %s", strerror(errno)); |
159 | if (stdb == 1) { | |
0825a747 | 160 | err(0, "ignored duplicate: %s", nf); |
4b9c212b EA |
161 | continue; |
162 | } | |
0825a747 | 163 | ++reccnt; |
06c161de | 164 | |
0825a747 | 165 | /* Store references for other names. */ |
a86ecba7 | 166 | (void)strcpy((char *)(data.data), nf); |
06c161de | 167 | |
1d6e0482 | 168 | data.size = key.size; |
e41e2450 EA |
169 | key.data = namebuf; |
170 | np = namebuf; | |
0825a747 | 171 | for (cp = nf; *cp != '\0'; *np++ = *cp++) |
06c161de EA |
172 | if (*cp == ':' || *cp == '|') { |
173 | *np = '\0'; | |
174 | key.size = strlen(namebuf) + 1; | |
0825a747 KB |
175 | if ((stdb = capdbp->put(capdbp, &key, &data, |
176 | R_NOOVERWRITE)) < 0) | |
4b9c212b EA |
177 | err(1, "put: %s", strerror(errno)); |
178 | if (stdb == 1) | |
0825a747 KB |
179 | err(0, |
180 | "ignored duplicate: %s", namebuf); | |
06c161de EA |
181 | np = namebuf; |
182 | continue; | |
0825a747 | 183 | } |
06c161de | 184 | } |
5a884762 | 185 | if (capdbp->close(capdbp) < 0) |
4bf71922 | 186 | err(1, "%s: %s", capdb, strerror(errno)); |
0825a747 | 187 | |
5a884762 | 188 | if (st == -1) |
4bf71922 | 189 | err(1, "file argument: %s", strerror(errno)); |
5a884762 | 190 | if (st == -2) |
4b9c212b | 191 | err(1, "potential reference loop detected"); |
0825a747 | 192 | |
06c161de EA |
193 | free(data.data); |
194 | free(nf); | |
195 | free(bp); | |
0825a747 | 196 | |
188c396b KB |
197 | if (verbose) |
198 | (void)printf("cap_mkdb: %d capability records\n", reccnt); | |
06c161de EA |
199 | } |
200 | ||
5a884762 | 201 | void |
06c161de EA |
202 | getnamefield(nf, bp) |
203 | char **nf, *bp; | |
204 | { | |
5a884762 | 205 | static size_t nfsize; |
06c161de EA |
206 | size_t newsize; |
207 | char *cp, tmp; | |
0825a747 | 208 | |
5a884762 | 209 | for (cp = bp; *cp != ':'; cp++); |
06c161de | 210 | |
5a884762 EA |
211 | tmp = *(cp + 1); |
212 | *(cp + 1) = '\0'; | |
06c161de EA |
213 | |
214 | if ((newsize = cp - bp + 1) > nfsize) { | |
5a884762 | 215 | if ((*nf = realloc(*nf, newsize)) == NULL) |
4b9c212b | 216 | err(1, "%s", strerror(errno)); |
06c161de EA |
217 | nfsize = newsize; |
218 | } | |
5a884762 EA |
219 | (void)strcpy(*nf, bp); |
220 | *(cp + 1) = tmp; | |
06c161de EA |
221 | } |
222 | ||
5a884762 | 223 | void |
06c161de EA |
224 | usage() |
225 | { | |
0825a747 | 226 | (void)fprintf(stderr, |
0d7a9f9e | 227 | "usage: cap_mkdb [-v] [-f outfile] file1 [file2 ...]\n"); |
0825a747 | 228 | exit(1); |
06c161de EA |
229 | } |
230 | ||
06c161de EA |
231 | #if __STDC__ |
232 | #include <stdarg.h> | |
233 | #else | |
234 | #include <varargs.h> | |
235 | #endif | |
236 | ||
5a884762 | 237 | void |
06c161de | 238 | #if __STDC__ |
4b9c212b | 239 | err(int fatal, const char *fmt, ...) |
06c161de | 240 | #else |
5a884762 EA |
241 | err(fmt, va_alist) |
242 | char *fmt; | |
0825a747 | 243 | va_dcl |
06c161de EA |
244 | #endif |
245 | { | |
5a884762 | 246 | va_list ap; |
06c161de | 247 | #if __STDC__ |
5a884762 | 248 | va_start(ap, fmt); |
06c161de | 249 | #else |
5a884762 | 250 | va_start(ap); |
06c161de | 251 | #endif |
e8e9e2d0 EA |
252 | |
253 | if (printnl) | |
254 | (void)fprintf(stderr, "\n"); | |
5a884762 EA |
255 | (void)fprintf(stderr, "cap_mkdb: "); |
256 | (void)vfprintf(stderr, fmt, ap); | |
257 | va_end(ap); | |
258 | (void)fprintf(stderr, "\n"); | |
4b9c212b EA |
259 | if (fatal) { |
260 | if (docapdbunlink) | |
261 | (void)unlink(capdb); | |
262 | exit(1); | |
263 | } | |
06c161de | 264 | } |