]> arthur.barton.de Git - netatalk.git/blob - bin/cnid/cnid_didname_verify.c
6e36dc6d60125c9a8819dc2893fb35c33d951917
[netatalk.git] / bin / cnid / cnid_didname_verify.c
1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 1996, 1997, 1998, 1999, 2000
5  *      Sleepycat Software.  All rights reserved.
6  *
7  * Modified to check the consistency of didname.db by
8  * Joe Clarke <marcus@marcuscom.com>
9  *
10  * $Id: cnid_didname_verify.c,v 1.7.2.1 2001-12-31 20:14:18 srittau Exp $
11  */
12
13 #ifdef HAVE_CONFIG_H
14 #include "config.h"
15 #endif /* HAVE_CONFIG_H */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #ifdef HAVE_UNISTD_H
21 #include <unistd.h>
22 #endif /* HAVE_UNISTD_H */
23 #include <sys/param.h>
24
25 #include <db.h>
26
27 #include <atalk/cnid.h>
28 #include <atalk/util.h>
29
30 #ifndef MIN
31 #define MIN(a, b)  ((a) < (b) ? (a) : (b))
32 #endif /* ! MIN */
33
34 #define DBDIDNAME "didname.db"
35
36 int     main __P((int, char *[]));
37 void    usage __P((void));
38 void    version_check __P((void));
39
40 const char
41 *progname = "cnid_didname_verify";                      /* Program name. */
42
43 static __inline__ int compare_did(const DBT *a, const DBT *b) {
44     u_int32_t dida, didb;
45
46     memcpy(&dida, a->data, sizeof(dida));
47     memcpy(&didb, b->data, sizeof(didb));
48     return dida - didb;
49 }
50
51 #if DB_VERSION_MINOR > 1
52 static int compare_unix(DB *db, const DBT *a, const DBT *b)
53 #else /* DB_VERSION_MINOR < 1 */
54 static int compare_unix(const DBT *a, const DBT *b)
55 #endif /* DB_VERSION_MINOR */
56 {
57     u_int8_t *sa, *sb;
58     int len, ret;
59
60     if ((ret = compare_did(a, b)))
61         return ret;
62
63     sa = (u_int8_t *) a->data + 4;
64     sb = (u_int8_t *) b->data + 4;
65     for (len = MIN(a->size, b->size); len-- > 4; sa++, sb++)
66         if ((ret = (*sa - *sb)))
67             return ret;
68     return a->size - b->size;
69 }
70
71 int
72 main(argc, argv)
73 int argc;
74 char *argv[];
75 {
76     extern char *optarg;
77     extern int optind;
78     DB *dbp;
79     DB_ENV *dbenv;
80     int ch, e_close, exitval, nflag, quiet, ret, t_ret;
81     char *home;
82
83     version_check();
84
85     dbenv = NULL;
86     e_close = exitval = nflag = quiet = 0;
87     home = NULL;
88     while ((ch = getopt(argc, argv, "h:NqV")) != EOF)
89         switch (ch) {
90         case 'h':
91             home = optarg;
92             break;
93         case 'N':
94             nflag = 1;
95             if ((ret = db_env_set_panicstate(0)) != 0) {
96                 fprintf(stderr,
97                         "%s: db_env_set_panicstate: %s\n",
98                         progname, db_strerror(ret));
99                 exit (1);
100             }
101             break;
102             break;
103         case 'q':
104             quiet = 1;
105             break;
106         case 'V':
107             printf("%s\n", db_version(NULL, NULL, NULL));
108             exit(0);
109         case '?':
110         default:
111             usage();
112         }
113     argc -= optind;
114     argv += optind;
115
116     /*
117      * Create an environment object and initialize it for error
118      * reporting.
119      */
120     if ((ret = db_env_create(&dbenv, 0)) != 0) {
121         fprintf(stderr, "%s: db_env_create: %s\n",
122                 progname, db_strerror(ret));
123         goto shutdown;
124     }
125     e_close = 1;
126
127     /*
128      * XXX
129      * We'd prefer to have error output configured while calling
130      * db_env_create, but there's no way to turn it off once it's
131      * turned on.
132      */
133     if (!quiet) {
134         dbenv->set_errfile(dbenv, stderr);
135         dbenv->set_errpfx(dbenv, progname);
136     }
137
138 #if DB_VERSION_MINOR > 1
139     if (nflag && (ret = dbenv->set_mutexlocks(dbenv, 0)) != 0) {
140         dbenv->err(dbenv, ret, "set_mutexlocks");
141         goto shutdown;
142     }
143 #else /* DB_VERSION_MINOR < 1 */
144     if (nflag && (ret = db_env_set_mutexlocks(0)) != 0) {
145         dbenv->err(dbenv, ret, "db_env_set_mutexlocks");
146         goto shutdown;
147     }
148 #endif /* DB_VERSION_MINOR */
149
150     /*
151      * Attach to an mpool if it exists, but if that fails, attach
152      * to a private region.
153      */
154     if ((ret = dbenv->open(dbenv,
155                            home, DB_INIT_MPOOL | DB_USE_ENVIRON, 0)) != 0 &&
156             (ret = dbenv->open(dbenv, home,
157                                DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_USE_ENVIRON, 0)) != 0) {
158         dbenv->err(dbenv, ret, "open");
159         goto shutdown;
160     }
161
162     if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
163         fprintf(stderr,
164                 "%s: db_create: %s\n", progname, db_strerror(ret));
165         goto shutdown;
166     }
167
168     /* This is the crux of the program.  We need to make sure we verify
169      * using the correct sort routine.  Else, the database will report
170      * corruption. */
171     dbp->set_bt_compare(dbp, &compare_unix);
172
173     if (!quiet) {
174         dbp->set_errfile(dbp, stderr);
175         dbp->set_errpfx(dbp, progname);
176     }
177     if ((ret = dbp->verify(dbp, DBDIDNAME, NULL, NULL, 0)) != 0)
178         dbp->err(dbp, ret, "DB->verify: %s", DBDIDNAME);
179     if ((t_ret = dbp->close(dbp, 0)) != 0 && ret == 0) {
180         dbp->err(dbp, ret, "DB->close: %s", DBDIDNAME);
181         ret = t_ret;
182     }
183     if (ret != 0)
184         goto shutdown;
185
186     if (0) {
187 shutdown:       exitval = 1;
188     }
189     if (e_close && (ret = dbenv->close(dbenv, 0)) != 0) {
190         exitval = 1;
191         fprintf(stderr,
192                 "%s: dbenv->close: %s\n", progname, db_strerror(ret));
193     }
194
195     return (exitval);
196 }
197
198 void
199 usage()
200 {
201     fprintf(stderr, "usage: db_verify [-NqV] [-h home] ...\n");
202     exit (1);
203 }
204
205 void
206 version_check()
207 {
208     int v_major, v_minor, v_patch;
209
210     /* Make sure we're loaded with the right version of the DB library. */
211     (void)db_version(&v_major, &v_minor, &v_patch);
212     if (v_major != DB_VERSION_MAJOR ||
213             v_minor != DB_VERSION_MINOR || v_patch != DB_VERSION_PATCH) {
214         fprintf(stderr,
215                 "%s: version %d.%d.%d doesn't match library version %d.%d.%d\n",
216                 progname, DB_VERSION_MAJOR, DB_VERSION_MINOR,
217                 DB_VERSION_PATCH, v_major, v_minor, v_patch);
218         exit (1);
219     }
220 }