1/* mdb_drop.c - memory-mapped database delete tool */
2/*
3 * Copyright 2016-2018 Howard Chu, Symas Corp.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted only as authorized by the OpenLDAP
8 * Public License.
9 *
10 * A copy of this license is available in the file LICENSE in the
11 * top-level directory of the distribution or, alternatively, at
12 * <http://www.OpenLDAP.org/license.html>.
13 */
14#include <stdio.h>
15#include <errno.h>
16#include <stdlib.h>
17#include <string.h>
18#include <ctype.h>
19#include <unistd.h>
20#include <signal.h>
21#include "lmdb.h"
22
23static volatile sig_atomic_t gotsig;
24
25static void dumpsig( int sig )
26{
27 gotsig=1;
28}
29
30static void usage(char *prog)
31{
32 fprintf(stderr, "usage: %s [-V] [-n] [-d] [-s subdb] dbpath\n", prog);
33 exit(EXIT_FAILURE);
34}
35
36int main(int argc, char *argv[])
37{
38 int i, rc;
39 MDB_env *env;
40 MDB_txn *txn;
41 MDB_dbi dbi;
42 char *prog = argv[0];
43 char *envname;
44 char *subname = NULL;
45 int envflags = 0, delete = 0;
46
47 if (argc < 2) {
48 usage(prog);
49 }
50
51 /* -d: delete the db, don't just empty it
52 * -s: drop the named subDB
53 * -n: use NOSUBDIR flag on env_open
54 * -V: print version and exit
55 * (default) empty the main DB
56 */
57 while ((i = getopt(argc, argv, "dns:V")) != EOF) {
58 switch(i) {
59 case 'V':
60 printf("%s\n", MDB_VERSION_STRING);
61 exit(0);
62 break;
63 case 'd':
64 delete = 1;
65 break;
66 case 'n':
67 envflags |= MDB_NOSUBDIR;
68 break;
69 case 's':
70 subname = optarg;
71 break;
72 default:
73 usage(prog);
74 }
75 }
76
77 if (optind != argc - 1)
78 usage(prog);
79
80#ifdef SIGPIPE
81 signal(SIGPIPE, dumpsig);
82#endif
83#ifdef SIGHUP
84 signal(SIGHUP, dumpsig);
85#endif
86 signal(SIGINT, dumpsig);
87 signal(SIGTERM, dumpsig);
88
89 envname = argv[optind];
90 rc = mdb_env_create(&env);
91 if (rc) {
92 fprintf(stderr, "mdb_env_create failed, error %d %s\n", rc, mdb_strerror(rc));
93 return EXIT_FAILURE;
94 }
95
96 mdb_env_set_maxdbs(env, 2);
97
98 rc = mdb_env_open(env, envname, envflags, 0664);
99 if (rc) {
100 fprintf(stderr, "mdb_env_open failed, error %d %s\n", rc, mdb_strerror(rc));
101 goto env_close;
102 }
103
104 rc = mdb_txn_begin(env, NULL, 0, &txn);
105 if (rc) {
106 fprintf(stderr, "mdb_txn_begin failed, error %d %s\n", rc, mdb_strerror(rc));
107 goto env_close;
108 }
109
110 rc = mdb_open(txn, subname, 0, &dbi);
111 if (rc) {
112 fprintf(stderr, "mdb_open failed, error %d %s\n", rc, mdb_strerror(rc));
113 goto txn_abort;
114 }
115
116 rc = mdb_drop(txn, dbi, delete);
117 if (rc) {
118 fprintf(stderr, "mdb_drop failed, error %d %s\n", rc, mdb_strerror(rc));
119 goto txn_abort;
120 }
121 rc = mdb_txn_commit(txn);
122 if (rc) {
123 fprintf(stderr, "mdb_txn_commit failed, error %d %s\n", rc, mdb_strerror(rc));
124 goto txn_abort;
125 }
126 txn = NULL;
127
128txn_abort:
129 if (txn)
130 mdb_txn_abort(txn);
131env_close:
132 mdb_env_close(env);
133
134 return rc ? EXIT_FAILURE : EXIT_SUCCESS;
135}
136