netgroup_mkdb.c revision 1.16 1 1.16 perry /* $NetBSD: netgroup_mkdb.c,v 1.16 2007/12/15 19:44:56 perry Exp $ */
2 1.5 christos
3 1.1 christos /*
4 1.1 christos * Copyright (c) 1994 Christos Zoulas
5 1.1 christos * All rights reserved.
6 1.1 christos *
7 1.1 christos * Redistribution and use in source and binary forms, with or without
8 1.1 christos * modification, are permitted provided that the following conditions
9 1.1 christos * are met:
10 1.1 christos * 1. Redistributions of source code must retain the above copyright
11 1.1 christos * notice, this list of conditions and the following disclaimer.
12 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 christos * notice, this list of conditions and the following disclaimer in the
14 1.1 christos * documentation and/or other materials provided with the distribution.
15 1.1 christos * 3. All advertising materials mentioning features or use of this software
16 1.1 christos * must display the following acknowledgement:
17 1.1 christos * This product includes software developed by Christos Zoulas.
18 1.1 christos * 4. The name of the author may not be used to endorse or promote products
19 1.1 christos * derived from this software without specific prior written permission.
20 1.1 christos *
21 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
22 1.1 christos * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 1.1 christos * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 1.1 christos * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
25 1.1 christos * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 1.1 christos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 1.1 christos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 1.1 christos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 1.1 christos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 1.1 christos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 1.1 christos * SUCH DAMAGE.
32 1.1 christos */
33 1.8 lukem #include <sys/cdefs.h>
34 1.1 christos #ifndef lint
35 1.16 perry __RCSID("$NetBSD: netgroup_mkdb.c,v 1.16 2007/12/15 19:44:56 perry Exp $");
36 1.1 christos #endif
37 1.1 christos
38 1.1 christos #include <sys/types.h>
39 1.2 christos #include <sys/param.h>
40 1.1 christos #include <sys/stat.h>
41 1.1 christos #include <stdlib.h>
42 1.1 christos #include <stddef.h>
43 1.1 christos #include <unistd.h>
44 1.1 christos #include <fcntl.h>
45 1.1 christos #include <db.h>
46 1.1 christos #include <err.h>
47 1.1 christos #include <errno.h>
48 1.1 christos #include <stdio.h>
49 1.1 christos #include <string.h>
50 1.6 lukem #include <stringlist.h>
51 1.4 christos #define _NETGROUP_PRIVATE
52 1.1 christos #include <netgroup.h>
53 1.1 christos #include <assert.h>
54 1.1 christos
55 1.1 christos #include "str.h"
56 1.1 christos #include "util.h"
57 1.1 christos
58 1.4 christos #define DEBUG_NG
59 1.4 christos
60 1.1 christos #define NEW(a) (a *) emalloc(sizeof(a))
61 1.1 christos
62 1.1 christos struct nentry {
63 1.1 christos int n_type;
64 1.1 christos size_t n_size; /* Buffer size required for printing */
65 1.1 christos union {
66 1.1 christos char *_name;
67 1.1 christos struct netgroup *_group;
68 1.1 christos } _n;
69 1.1 christos #define n_name _n._name
70 1.1 christos #define n_group _n._group
71 1.1 christos struct nentry *n_next;
72 1.1 christos };
73 1.1 christos
74 1.1 christos
75 1.14 christos static void cleanup(void);
76 1.14 christos static DB *ng_insert(DB *, const char *);
77 1.14 christos static void ng_reventry(DB *, DB *, struct nentry *, char *,
78 1.14 christos size_t, StringList *);
79 1.14 christos static void ng_print(struct nentry *, struct string *);
80 1.14 christos static void ng_rprint(DB *, struct string *);
81 1.14 christos static DB *ng_reverse(DB *, size_t);
82 1.14 christos static DB *ng_load(const char *);
83 1.14 christos static void ng_write(DB *, DB *, int);
84 1.14 christos static void ng_rwrite(DB *, DB *, int);
85 1.16 perry static void usage(void) __dead;
86 1.1 christos
87 1.1 christos #ifdef DEBUG_NG
88 1.8 lukem static int debug = 0;
89 1.14 christos static void ng_dump(DB *);
90 1.14 christos static void ng_rdump(DB *);
91 1.1 christos #endif /* DEBUG_NG */
92 1.14 christos static int dups = 0;
93 1.1 christos
94 1.4 christos
95 1.3 christos static const char ng_empty[] = "";
96 1.3 christos #define NG_EMPTY(a) ((a) ? (a) : ng_empty)
97 1.3 christos
98 1.1 christos static char *dbname = _PATH_NETGROUP_DB;
99 1.1 christos
100 1.1 christos int
101 1.14 christos main(int argc, char **argv)
102 1.1 christos {
103 1.2 christos DB *db, *ndb, *hdb, *udb;
104 1.2 christos int ch;
105 1.2 christos char buf[MAXPATHLEN];
106 1.2 christos char *fname = _PATH_NETGROUP;
107 1.2 christos
108 1.1 christos
109 1.14 christos while ((ch = getopt(argc, argv, "dDo:")) != -1)
110 1.1 christos switch (ch) {
111 1.4 christos #ifdef DEBUG_NG
112 1.4 christos case 'd':
113 1.4 christos debug++;
114 1.4 christos break;
115 1.4 christos #endif
116 1.1 christos case 'o':
117 1.1 christos dbname = optarg;
118 1.1 christos break;
119 1.1 christos
120 1.14 christos case 'D':
121 1.14 christos dups++;
122 1.14 christos break;
123 1.14 christos
124 1.1 christos case '?':
125 1.1 christos default:
126 1.1 christos usage();
127 1.1 christos }
128 1.1 christos
129 1.1 christos argc -= optind;
130 1.1 christos argv += optind;
131 1.1 christos
132 1.2 christos if (argc == 1)
133 1.2 christos fname = *argv;
134 1.2 christos else if (argc > 1)
135 1.1 christos usage();
136 1.1 christos
137 1.2 christos if (atexit(cleanup))
138 1.2 christos err(1, "Cannot install exit handler");
139 1.2 christos
140 1.1 christos /* Read and parse the netgroup file */
141 1.2 christos ndb = ng_load(fname);
142 1.1 christos #ifdef DEBUG_NG
143 1.4 christos if (debug) {
144 1.14 christos (void)fprintf(stderr, "#### Database\n");
145 1.4 christos ng_dump(ndb);
146 1.4 christos }
147 1.1 christos #endif
148 1.1 christos
149 1.1 christos /* Reverse the database by host */
150 1.1 christos hdb = ng_reverse(ndb, offsetof(struct netgroup, ng_host));
151 1.1 christos #ifdef DEBUG_NG
152 1.4 christos if (debug) {
153 1.14 christos (void)fprintf(stderr, "#### Reverse by host\n");
154 1.4 christos ng_rdump(hdb);
155 1.4 christos }
156 1.1 christos #endif
157 1.1 christos
158 1.1 christos /* Reverse the database by user */
159 1.1 christos udb = ng_reverse(ndb, offsetof(struct netgroup, ng_user));
160 1.1 christos #ifdef DEBUG_NG
161 1.4 christos if (debug) {
162 1.14 christos (void)fprintf(stderr, "#### Reverse by user\n");
163 1.4 christos ng_rdump(udb);
164 1.4 christos }
165 1.1 christos #endif
166 1.1 christos
167 1.14 christos (void)snprintf(buf, sizeof(buf), "%s.tmp", dbname);
168 1.2 christos
169 1.2 christos db = dbopen(buf, O_RDWR | O_CREAT | O_EXCL,
170 1.14 christos (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH), DB_HASH, NULL);
171 1.1 christos if (!db)
172 1.10 itojun err(1, "%s", buf);
173 1.1 christos
174 1.1 christos ng_write(db, ndb, _NG_KEYBYNAME);
175 1.1 christos ng_rwrite(db, udb, _NG_KEYBYUSER);
176 1.1 christos ng_rwrite(db, hdb, _NG_KEYBYHOST);
177 1.2 christos
178 1.2 christos if ((db->close)(db))
179 1.2 christos err(1, "Error closing database");
180 1.2 christos
181 1.2 christos if (rename(buf, dbname) == -1)
182 1.2 christos err(1, "Cannot rename `%s' to `%s'", buf, dbname);
183 1.2 christos
184 1.1 christos return 0;
185 1.1 christos }
186 1.1 christos
187 1.1 christos
188 1.1 christos /*
189 1.2 christos * cleanup(): Remove temporary files upon exit
190 1.2 christos */
191 1.2 christos static void
192 1.14 christos cleanup(void)
193 1.2 christos {
194 1.2 christos char buf[MAXPATHLEN];
195 1.14 christos (void)snprintf(buf, sizeof(buf), "%s.tmp", dbname);
196 1.14 christos (void)unlink(buf);
197 1.2 christos }
198 1.2 christos
199 1.2 christos
200 1.2 christos
201 1.2 christos /*
202 1.1 christos * ng_load(): Load the netgroup database from a file
203 1.1 christos */
204 1.2 christos static DB *
205 1.14 christos ng_load(const char *fname)
206 1.1 christos {
207 1.1 christos FILE *fp;
208 1.1 christos DB *db;
209 1.1 christos char *buf;
210 1.1 christos size_t size;
211 1.1 christos struct nentry *tail, *head, *e;
212 1.1 christos char *p, *name;
213 1.1 christos struct netgroup *ng;
214 1.1 christos DBT data, key;
215 1.1 christos
216 1.1 christos /* Open the netgroup file */
217 1.1 christos if ((fp = fopen(fname, "r")) == NULL)
218 1.10 itojun err(1, "%s", fname);
219 1.1 christos
220 1.1 christos db = dbopen(NULL, O_RDWR | O_CREAT | O_EXCL, 0, DB_HASH, NULL);
221 1.1 christos
222 1.1 christos if (db == NULL)
223 1.1 christos err(1, "dbopen");
224 1.1 christos
225 1.15 christos while ((buf = fparseln(fp, &size, NULL, NULL, 0)) != NULL) {
226 1.1 christos tail = head = NULL;
227 1.1 christos p = buf;
228 1.1 christos
229 1.1 christos while (p != NULL) {
230 1.1 christos switch (_ng_parse(&p, &name, &ng)) {
231 1.1 christos case _NG_NONE:
232 1.1 christos /* done with this one */
233 1.1 christos p = NULL;
234 1.1 christos free(buf);
235 1.1 christos if (head == NULL)
236 1.1 christos break;
237 1.1 christos
238 1.14 christos key.data = (u_char *)head->n_name;
239 1.1 christos key.size = strlen(head->n_name) + 1;
240 1.14 christos data.data = (u_char *)&head;
241 1.1 christos data.size = sizeof(head);
242 1.14 christos switch ((db->put)(db, &key, &data,
243 1.14 christos R_NOOVERWRITE)) {
244 1.1 christos case 0:
245 1.1 christos break;
246 1.1 christos
247 1.1 christos case 1:
248 1.12 grant warnx("Duplicate entry netgroup `%s'",
249 1.14 christos head->n_name);
250 1.1 christos break;
251 1.1 christos
252 1.1 christos case -1:
253 1.1 christos err(1, "put");
254 1.1 christos break;
255 1.1 christos
256 1.1 christos default:
257 1.1 christos abort();
258 1.1 christos break;
259 1.1 christos }
260 1.1 christos break;
261 1.1 christos
262 1.1 christos case _NG_NAME:
263 1.1 christos e = NEW(struct nentry);
264 1.1 christos e->n_type = _NG_NAME;
265 1.1 christos e->n_name = name;
266 1.1 christos e->n_next = NULL;
267 1.1 christos e->n_size = size;
268 1.1 christos if (tail == NULL)
269 1.1 christos head = tail = e;
270 1.1 christos else {
271 1.1 christos tail->n_next = e;
272 1.1 christos tail = e;
273 1.1 christos }
274 1.1 christos break;
275 1.1 christos
276 1.1 christos case _NG_GROUP:
277 1.4 christos if (tail == NULL) {
278 1.4 christos char fmt[BUFSIZ];
279 1.4 christos _ng_print(fmt, sizeof(fmt), ng);
280 1.4 christos errx(1, "no netgroup key for %s", fmt);
281 1.4 christos }
282 1.1 christos else {
283 1.1 christos e = NEW(struct nentry);
284 1.1 christos e->n_type = _NG_GROUP;
285 1.1 christos e->n_group = ng;
286 1.1 christos e->n_next = NULL;
287 1.1 christos e->n_size = size;
288 1.1 christos tail->n_next = e;
289 1.1 christos tail = e;
290 1.1 christos }
291 1.1 christos break;
292 1.1 christos
293 1.9 lukem case _NG_ERROR:
294 1.9 lukem errx(1, "Fatal error at `%s'", p);
295 1.9 lukem break;
296 1.9 lukem
297 1.1 christos default:
298 1.1 christos abort();
299 1.1 christos break;
300 1.1 christos }
301 1.1 christos }
302 1.1 christos }
303 1.14 christos (void)fclose(fp);
304 1.1 christos return db;
305 1.1 christos }
306 1.1 christos
307 1.1 christos
308 1.1 christos /*
309 1.1 christos * ng_insert(): Insert named key into the database, and return its associated
310 1.1 christos * string database
311 1.1 christos */
312 1.1 christos static DB *
313 1.14 christos ng_insert(DB *db, const char *name)
314 1.1 christos {
315 1.1 christos DB *xdb = NULL;
316 1.1 christos DBT key, data;
317 1.1 christos
318 1.14 christos key.data = (u_char *)name;
319 1.1 christos key.size = strlen(name) + 1;
320 1.1 christos
321 1.1 christos switch ((db->get)(db, &key, &data, 0)) {
322 1.1 christos case 0:
323 1.14 christos (void)memcpy(&xdb, data.data, sizeof(xdb));
324 1.1 christos break;
325 1.1 christos
326 1.1 christos case 1:
327 1.1 christos xdb = dbopen(NULL, O_RDWR | O_CREAT | O_EXCL, 0, DB_HASH, NULL);
328 1.1 christos if (xdb == NULL)
329 1.1 christos err(1, "dbopen");
330 1.1 christos
331 1.14 christos data.data = (u_char *)&xdb;
332 1.1 christos data.size = sizeof(xdb);
333 1.1 christos switch ((db->put)(db, &key, &data, R_NOOVERWRITE)) {
334 1.1 christos case 0:
335 1.1 christos break;
336 1.1 christos
337 1.1 christos case -1:
338 1.1 christos err(1, "db put `%s'", name);
339 1.1 christos break;
340 1.1 christos
341 1.1 christos case 1:
342 1.1 christos default:
343 1.1 christos abort();
344 1.1 christos }
345 1.1 christos break;
346 1.1 christos
347 1.1 christos case -1:
348 1.1 christos err(1, "db get `%s'", name);
349 1.1 christos break;
350 1.1 christos
351 1.1 christos default:
352 1.1 christos abort();
353 1.1 christos break;
354 1.1 christos }
355 1.1 christos
356 1.1 christos return xdb;
357 1.1 christos }
358 1.1 christos
359 1.1 christos
360 1.1 christos /*
361 1.1 christos * ng_reventry(): Recursively add all the netgroups to the group entry.
362 1.1 christos */
363 1.1 christos static void
364 1.14 christos ng_reventry(DB *db, DB *udb, struct nentry *fe, char *name, size_t s,
365 1.14 christos StringList *ss)
366 1.1 christos {
367 1.1 christos DBT key, data;
368 1.1 christos struct nentry *e;
369 1.1 christos struct netgroup *ng;
370 1.1 christos char *p;
371 1.1 christos DB *xdb;
372 1.1 christos
373 1.7 christos if (sl_find(ss, fe->n_name) != NULL) {
374 1.14 christos _ng_cycle(name, ss);
375 1.1 christos return;
376 1.1 christos }
377 1.7 christos sl_add(ss, fe->n_name);
378 1.1 christos
379 1.1 christos for (e = fe->n_next; e != NULL; e = e->n_next)
380 1.1 christos switch (e->n_type) {
381 1.1 christos case _NG_GROUP:
382 1.14 christos if (!dups)
383 1.14 christos sl_delete(ss, fe->n_name, 0);
384 1.1 christos ng = e->n_group;
385 1.1 christos p = _ng_makekey(*((char **)(((char *) ng) + s)),
386 1.1 christos ng->ng_domain, e->n_size);
387 1.1 christos xdb = ng_insert(udb, p);
388 1.14 christos key.data = (u_char *)name;
389 1.1 christos key.size = strlen(name) + 1;
390 1.1 christos data.data = NULL;
391 1.1 christos data.size = 0;
392 1.1 christos switch ((xdb->put)(xdb, &key, &data, R_NOOVERWRITE)) {
393 1.1 christos case 0:
394 1.1 christos case 1:
395 1.1 christos break;
396 1.1 christos
397 1.1 christos case -1:
398 1.1 christos err(1, "db put `%s'", name);
399 1.1 christos return;
400 1.1 christos
401 1.1 christos default:
402 1.1 christos abort();
403 1.1 christos break;
404 1.1 christos }
405 1.1 christos free(p);
406 1.1 christos break;
407 1.1 christos
408 1.1 christos case _NG_NAME:
409 1.1 christos key.data = (u_char *) e->n_name;
410 1.1 christos key.size = strlen(e->n_name) + 1;
411 1.1 christos switch ((db->get)(db, &key, &data, 0)) {
412 1.7 christos struct nentry *rfe;
413 1.1 christos case 0:
414 1.14 christos (void)memcpy(&rfe, data.data, sizeof(rfe));
415 1.7 christos ng_reventry(db, udb, rfe, name, s, ss);
416 1.1 christos break;
417 1.1 christos
418 1.1 christos case 1:
419 1.1 christos break;
420 1.1 christos
421 1.1 christos case -1:
422 1.1 christos err(1, "db get `%s'", e->n_name);
423 1.1 christos return;
424 1.1 christos
425 1.1 christos default:
426 1.1 christos abort();
427 1.1 christos return;
428 1.1 christos }
429 1.1 christos break;
430 1.1 christos
431 1.1 christos default:
432 1.1 christos abort();
433 1.1 christos break;
434 1.1 christos }
435 1.1 christos }
436 1.1 christos
437 1.1 christos
438 1.1 christos /*
439 1.1 christos * ng_reverse(): Reverse the database
440 1.1 christos */
441 1.1 christos static DB *
442 1.14 christos ng_reverse(DB *db, size_t s)
443 1.1 christos {
444 1.1 christos int pos;
445 1.6 lukem StringList *sl;
446 1.1 christos DBT key, data;
447 1.1 christos struct nentry *fe;
448 1.1 christos DB *udb = dbopen(NULL, O_RDWR | O_CREAT | O_EXCL, 0,
449 1.14 christos DB_HASH, NULL);
450 1.1 christos
451 1.1 christos if (udb == NULL)
452 1.1 christos err(1, "dbopen");
453 1.1 christos
454 1.1 christos for (pos = R_FIRST;; pos = R_NEXT)
455 1.1 christos switch ((db->seq)(db, &key, &data, pos)) {
456 1.1 christos case 0:
457 1.6 lukem sl = sl_init();
458 1.14 christos (void)memcpy(&fe, data.data, sizeof(fe));
459 1.1 christos ng_reventry(db, udb, fe, (char *) key.data, s, sl);
460 1.6 lukem sl_free(sl, 0);
461 1.1 christos break;
462 1.1 christos
463 1.1 christos case 1:
464 1.1 christos return udb;
465 1.1 christos
466 1.1 christos case -1:
467 1.1 christos err(1, "seq");
468 1.1 christos return udb;
469 1.1 christos }
470 1.1 christos
471 1.1 christos return udb;
472 1.1 christos }
473 1.1 christos
474 1.1 christos
475 1.1 christos /*
476 1.1 christos * ng_print(): Pretty print a netgroup entry
477 1.1 christos */
478 1.1 christos static void
479 1.14 christos ng_print(struct nentry *e, struct string *str)
480 1.1 christos {
481 1.13 christos char *ptr;
482 1.4 christos
483 1.4 christos if (e->n_next == NULL) {
484 1.4 christos str_append(str, "", ' ');
485 1.4 christos return;
486 1.4 christos }
487 1.1 christos
488 1.13 christos ptr = emalloc(e->n_size);
489 1.13 christos
490 1.1 christos for (e = e->n_next; e != NULL; e = e->n_next) {
491 1.1 christos switch (e->n_type) {
492 1.1 christos case _NG_NAME:
493 1.14 christos (void)snprintf(ptr, e->n_size, "%s", e->n_name);
494 1.1 christos break;
495 1.1 christos
496 1.1 christos case _NG_GROUP:
497 1.14 christos (void)snprintf(ptr, e->n_size, "(%s,%s,%s)",
498 1.14 christos NG_EMPTY(e->n_group->ng_host),
499 1.14 christos NG_EMPTY(e->n_group->ng_user),
500 1.14 christos NG_EMPTY(e->n_group->ng_domain));
501 1.1 christos break;
502 1.1 christos
503 1.1 christos default:
504 1.12 grant errx(1, "Internal error: Bad netgroup type");
505 1.1 christos break;
506 1.1 christos }
507 1.1 christos str_append(str, ptr, ' ');
508 1.1 christos }
509 1.1 christos free(ptr);
510 1.1 christos }
511 1.1 christos
512 1.1 christos
513 1.1 christos /*
514 1.1 christos * ng_rprint(): Pretty print all reverse netgroup mappings in the given entry
515 1.1 christos */
516 1.1 christos static void
517 1.14 christos ng_rprint(DB *db, struct string *str)
518 1.1 christos {
519 1.1 christos int pos;
520 1.1 christos DBT key, data;
521 1.1 christos
522 1.1 christos for (pos = R_FIRST;; pos = R_NEXT)
523 1.1 christos switch ((db->seq)(db, &key, &data, pos)) {
524 1.1 christos case 0:
525 1.14 christos str_append(str, (char *)key.data, ',');
526 1.1 christos break;
527 1.1 christos
528 1.1 christos case 1:
529 1.1 christos return;
530 1.1 christos
531 1.1 christos default:
532 1.1 christos err(1, "seq");
533 1.1 christos break;
534 1.1 christos }
535 1.1 christos }
536 1.1 christos
537 1.1 christos
538 1.1 christos #ifdef DEBUG_NG
539 1.1 christos /*
540 1.1 christos * ng_dump(): Pretty print all netgroups in the given database
541 1.1 christos */
542 1.1 christos static void
543 1.14 christos ng_dump(DB *db)
544 1.1 christos {
545 1.1 christos int pos;
546 1.1 christos DBT key, data;
547 1.1 christos struct nentry *e;
548 1.1 christos struct string buf;
549 1.1 christos
550 1.1 christos for (pos = R_FIRST;; pos = R_NEXT)
551 1.1 christos switch ((db->seq)(db, &key, &data, pos)) {
552 1.1 christos case 0:
553 1.14 christos (void)memcpy(&e, data.data, sizeof(e));
554 1.1 christos str_init(&buf);
555 1.1 christos assert(e->n_type == _NG_NAME);
556 1.1 christos
557 1.1 christos ng_print(e, &buf);
558 1.14 christos (void)fprintf(stderr, "%s\t%s\n", e->n_name,
559 1.14 christos buf.s_str ? buf.s_str : "");
560 1.1 christos str_free(&buf);
561 1.1 christos break;
562 1.1 christos
563 1.1 christos case 1:
564 1.1 christos return;
565 1.1 christos
566 1.1 christos default:
567 1.1 christos err(1, "seq");
568 1.1 christos return;
569 1.1 christos }
570 1.1 christos }
571 1.1 christos
572 1.1 christos
573 1.1 christos /*
574 1.1 christos * ng_rdump(): Pretty print all reverse mappings in the given database
575 1.1 christos */
576 1.1 christos static void
577 1.14 christos ng_rdump(DB *db)
578 1.1 christos {
579 1.1 christos int pos;
580 1.1 christos DBT key, data;
581 1.1 christos DB *xdb;
582 1.1 christos struct string buf;
583 1.1 christos
584 1.1 christos for (pos = R_FIRST;; pos = R_NEXT)
585 1.1 christos switch ((db->seq)(db, &key, &data, pos)) {
586 1.1 christos case 0:
587 1.14 christos (void)memcpy(&xdb, data.data, sizeof(xdb));
588 1.1 christos str_init(&buf);
589 1.1 christos ng_rprint(xdb, &buf);
590 1.14 christos (void)fprintf(stderr, "%s\t%s\n",
591 1.14 christos (char *)key.data, buf.s_str ? buf.s_str : "");
592 1.1 christos str_free(&buf);
593 1.1 christos break;
594 1.1 christos
595 1.1 christos case 1:
596 1.1 christos return;
597 1.1 christos
598 1.1 christos default:
599 1.1 christos err(1, "seq");
600 1.1 christos return;
601 1.1 christos }
602 1.1 christos }
603 1.1 christos #endif /* DEBUG_NG */
604 1.1 christos
605 1.1 christos
606 1.1 christos /*
607 1.1 christos * ng_write(): Dump the database into a file.
608 1.1 christos */
609 1.1 christos static void
610 1.14 christos ng_write(DB *odb, DB *idb, int k)
611 1.1 christos {
612 1.1 christos int pos;
613 1.1 christos DBT key, data;
614 1.1 christos struct nentry *e;
615 1.1 christos struct string skey, sdata;
616 1.1 christos
617 1.1 christos for (pos = R_FIRST;; pos = R_NEXT)
618 1.1 christos switch ((idb->seq)(idb, &key, &data, pos)) {
619 1.1 christos case 0:
620 1.1 christos memcpy(&e, data.data, sizeof(e));
621 1.1 christos str_init(&skey);
622 1.1 christos str_init(&sdata);
623 1.1 christos assert(e->n_type == _NG_NAME);
624 1.1 christos
625 1.1 christos str_prepend(&skey, e->n_name, k);
626 1.1 christos ng_print(e, &sdata);
627 1.1 christos key.data = (u_char *) skey.s_str;
628 1.1 christos key.size = skey.s_len + 1;
629 1.1 christos data.data = (u_char *) sdata.s_str;
630 1.1 christos data.size = sdata.s_len + 1;
631 1.1 christos
632 1.1 christos switch ((odb->put)(odb, &key, &data, R_NOOVERWRITE)) {
633 1.1 christos case 0:
634 1.1 christos break;
635 1.1 christos
636 1.1 christos case -1:
637 1.1 christos err(1, "put");
638 1.1 christos break;
639 1.1 christos
640 1.1 christos case 1:
641 1.1 christos default:
642 1.1 christos abort();
643 1.1 christos break;
644 1.1 christos }
645 1.1 christos
646 1.1 christos str_free(&skey);
647 1.1 christos str_free(&sdata);
648 1.1 christos break;
649 1.1 christos
650 1.1 christos case 1:
651 1.1 christos return;
652 1.1 christos
653 1.1 christos default:
654 1.1 christos err(1, "seq");
655 1.1 christos return;
656 1.1 christos }
657 1.1 christos }
658 1.1 christos
659 1.1 christos
660 1.1 christos /*
661 1.1 christos * ng_rwrite(): Write the database
662 1.1 christos */
663 1.1 christos static void
664 1.14 christos ng_rwrite(DB *odb, DB *idb, int k)
665 1.1 christos {
666 1.1 christos int pos;
667 1.1 christos DBT key, data;
668 1.1 christos DB *xdb;
669 1.1 christos struct string skey, sdata;
670 1.1 christos
671 1.1 christos for (pos = R_FIRST;; pos = R_NEXT)
672 1.1 christos switch ((idb->seq)(idb, &key, &data, pos)) {
673 1.1 christos case 0:
674 1.1 christos memcpy(&xdb, data.data, sizeof(xdb));
675 1.1 christos str_init(&skey);
676 1.1 christos str_init(&sdata);
677 1.1 christos
678 1.1 christos str_prepend(&skey, (char *) key.data, k);
679 1.1 christos ng_rprint(xdb, &sdata);
680 1.1 christos key.data = (u_char *) skey.s_str;
681 1.1 christos key.size = skey.s_len + 1;
682 1.1 christos data.data = (u_char *) sdata.s_str;
683 1.1 christos data.size = sdata.s_len + 1;
684 1.1 christos
685 1.1 christos switch ((odb->put)(odb, &key, &data, R_NOOVERWRITE)) {
686 1.1 christos case 0:
687 1.1 christos break;
688 1.1 christos
689 1.1 christos case -1:
690 1.1 christos err(1, "put");
691 1.1 christos break;
692 1.1 christos
693 1.1 christos case 1:
694 1.1 christos default:
695 1.1 christos abort();
696 1.1 christos break;
697 1.1 christos }
698 1.1 christos
699 1.1 christos str_free(&skey);
700 1.1 christos str_free(&sdata);
701 1.1 christos break;
702 1.1 christos
703 1.1 christos case 1:
704 1.1 christos return;
705 1.1 christos
706 1.1 christos default:
707 1.1 christos err(1, "seq");
708 1.1 christos return;
709 1.1 christos }
710 1.1 christos }
711 1.1 christos
712 1.1 christos
713 1.1 christos /*
714 1.1 christos * usage(): Print usage message and exit
715 1.1 christos */
716 1.1 christos static void
717 1.14 christos usage(void)
718 1.1 christos {
719 1.11 cgd
720 1.14 christos (void)fprintf(stderr, "Usage: %s [-D] [-o db] [<file>]\n",
721 1.14 christos getprogname());
722 1.1 christos exit(1);
723 1.1 christos }
724