s3:smbd: convert connections.c to use only dbrwap wrapper functions
[Samba/gbeck.git] / source3 / utils / dbwrap_tool.c
blobd6aea126b8afeedb813e5c044ca2a281b88d2d3e
1 /*
2 Samba Unix/Linux CIFS implementation
4 low level TDB/CTDB tool using the dbwrap interface
6 Copyright (C) 2009 Michael Adam <obnox@samba.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
23 #include "system/filesys.h"
24 #include "popt_common.h"
25 #include "dbwrap/dbwrap.h"
26 #include "dbwrap/dbwrap_open.h"
27 #include "messages.h"
29 typedef enum { OP_FETCH, OP_STORE, OP_DELETE, OP_ERASE, OP_LISTKEYS } dbwrap_op;
31 typedef enum { TYPE_INT32, TYPE_UINT32 } dbwrap_type;
33 static int dbwrap_tool_fetch_int32(struct db_context *db,
34 const char *keyname,
35 void *data)
37 int32_t value;
39 value = dbwrap_fetch_int32(db, keyname);
40 d_printf("%d\n", value);
42 return 0;
45 static int dbwrap_tool_fetch_uint32(struct db_context *db,
46 const char *keyname,
47 void *data)
49 uint32_t value;
50 bool ret;
52 ret = dbwrap_fetch_uint32(db, keyname, &value);
53 if (ret) {
54 d_printf("%u\n", value);
55 return 0;
56 } else {
57 d_fprintf(stderr, "ERROR: could not fetch uint32 key '%s'\n",
58 keyname);
59 return -1;
63 static int dbwrap_tool_store_int32(struct db_context *db,
64 const char *keyname,
65 void *data)
67 NTSTATUS status;
68 int32_t value = *((int32_t *)data);
70 status = dbwrap_trans_store_int32(db, keyname, value);
72 if (!NT_STATUS_IS_OK(status)) {
73 d_fprintf(stderr, "ERROR: could not store int32 key '%s': %s\n",
74 keyname, nt_errstr(status));
75 return -1;
78 return 0;
81 static int dbwrap_tool_store_uint32(struct db_context *db,
82 const char *keyname,
83 void *data)
85 NTSTATUS status;
86 uint32_t value = *((uint32_t *)data);
88 status = dbwrap_trans_store_uint32(db, keyname, value);
90 if (!NT_STATUS_IS_OK(status)) {
91 d_fprintf(stderr,
92 "ERROR: could not store uint32 key '%s': %s\n",
93 keyname, nt_errstr(status));
94 return -1;
97 return 0;
100 static int dbwrap_tool_delete(struct db_context *db,
101 const char *keyname,
102 void *data)
104 NTSTATUS status;
106 status = dbwrap_trans_delete_bystring(db, keyname);
108 if (!NT_STATUS_IS_OK(status)) {
109 d_fprintf(stderr, "ERROR deleting record %s : %s\n",
110 keyname, nt_errstr(status));
111 return -1;
114 return 0;
117 static int delete_fn(struct db_record *rec, void *priv)
119 dbwrap_record_delete(rec);
120 return 0;
124 * dbwrap_tool_erase: erase the whole data base
125 * the keyname argument is not used.
127 static int dbwrap_tool_erase(struct db_context *db,
128 const char *keyname,
129 void *data)
131 NTSTATUS status;
133 status = dbwrap_traverse(db, delete_fn, NULL, NULL);
135 if (!NT_STATUS_IS_OK(status)) {
136 d_fprintf(stderr, "ERROR erasing the database\n");
137 return -1;
140 return 0;
143 static int listkey_fn(struct db_record *rec, void *private_data)
145 int length = dbwrap_record_get_key(rec).dsize;
146 unsigned char *p = (unsigned char *)dbwrap_record_get_key(rec).dptr;
148 while (length--) {
149 if (isprint(*p) && !strchr("\"\\", *p)) {
150 d_printf("%c", *p);
151 } else {
152 d_printf("\\%02X", *p);
154 p++;
157 d_printf("\n");
159 return 0;
162 static int dbwrap_tool_listkeys(struct db_context *db,
163 const char *keyname,
164 void *data)
166 NTSTATUS status;
168 status = dbwrap_traverse_read(db, listkey_fn, NULL, NULL);
170 if (!NT_STATUS_IS_OK(status)) {
171 d_fprintf(stderr, "ERROR listing db keys\n");
172 return -1;
175 return 0;
178 struct dbwrap_op_dispatch_table {
179 dbwrap_op op;
180 dbwrap_type type;
181 int (*cmd)(struct db_context *db,
182 const char *keyname,
183 void *data);
186 struct dbwrap_op_dispatch_table dispatch_table[] = {
187 { OP_FETCH, TYPE_INT32, dbwrap_tool_fetch_int32 },
188 { OP_FETCH, TYPE_UINT32, dbwrap_tool_fetch_uint32 },
189 { OP_STORE, TYPE_INT32, dbwrap_tool_store_int32 },
190 { OP_STORE, TYPE_UINT32, dbwrap_tool_store_uint32 },
191 { OP_DELETE, TYPE_INT32, dbwrap_tool_delete },
192 { OP_ERASE, TYPE_INT32, dbwrap_tool_erase },
193 { OP_LISTKEYS, TYPE_INT32, dbwrap_tool_listkeys },
194 { 0, 0, NULL },
197 int main(int argc, const char **argv)
199 struct tevent_context *evt_ctx;
200 struct messaging_context *msg_ctx;
201 struct db_context *db;
203 uint16_t count;
205 const char *dbname;
206 const char *opname;
207 dbwrap_op op;
208 const char *keyname = "";
209 const char *keytype = "int32";
210 dbwrap_type type;
211 const char *valuestr = "0";
212 int32_t value = 0;
214 TALLOC_CTX *mem_ctx = talloc_stackframe();
216 int ret = 1;
218 struct poptOption popt_options[] = {
219 POPT_AUTOHELP
220 POPT_COMMON_SAMBA
221 POPT_TABLEEND
223 int opt;
224 const char **extra_argv;
225 int extra_argc = 0;
226 poptContext pc;
228 load_case_tables();
229 lp_set_cmdline("log level", "0");
230 setup_logging(argv[0], DEBUG_STDERR);
232 pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
234 while ((opt = poptGetNextOpt(pc)) != -1) {
235 switch (opt) {
236 default:
237 fprintf(stderr, "Invalid option %s: %s\n",
238 poptBadOption(pc, 0), poptStrerror(opt));
239 goto done;
243 /* setup the remaining options for the main program to use */
244 extra_argv = poptGetArgs(pc);
245 if (extra_argv) {
246 extra_argv++;
247 while (extra_argv[extra_argc]) extra_argc++;
250 lp_load_global(get_dyn_CONFIGFILE());
252 if ((extra_argc < 2) || (extra_argc > 5)) {
253 d_fprintf(stderr,
254 "USAGE: %s <database> <op> [<key> [<type> [<value>]]]\n"
255 " ops: fetch, store, delete, erase, listkeys\n"
256 " types: int32, uint32\n",
257 argv[0]);
258 goto done;
261 dbname = extra_argv[0];
262 opname = extra_argv[1];
264 if (strcmp(opname, "store") == 0) {
265 if (extra_argc != 5) {
266 d_fprintf(stderr, "ERROR: operation 'store' requires "
267 "value argument\n");
268 goto done;
270 valuestr = extra_argv[4];
271 keytype = extra_argv[3];
272 keyname = extra_argv[2];
273 op = OP_STORE;
274 } else if (strcmp(opname, "fetch") == 0) {
275 if (extra_argc != 4) {
276 d_fprintf(stderr, "ERROR: operation 'fetch' requires "
277 "type but not value argument\n");
278 goto done;
280 op = OP_FETCH;
281 keytype = extra_argv[3];
282 keyname = extra_argv[2];
283 } else if (strcmp(opname, "delete") == 0) {
284 if (extra_argc != 3) {
285 d_fprintf(stderr, "ERROR: operation 'delete' does "
286 "not allow type nor value argument\n");
287 goto done;
289 keyname = extra_argv[2];
290 op = OP_DELETE;
291 } else if (strcmp(opname, "erase") == 0) {
292 if (extra_argc != 2) {
293 d_fprintf(stderr, "ERROR: operation 'erase' does "
294 "not take a key argument\n");
295 goto done;
297 op = OP_ERASE;
298 } else if (strcmp(opname, "listkeys") == 0) {
299 if (extra_argc != 2) {
300 d_fprintf(stderr, "ERROR: operation 'listkeys' does "
301 "not take a key argument\n");
302 goto done;
304 op = OP_LISTKEYS;
305 } else {
306 d_fprintf(stderr,
307 "ERROR: invalid op '%s' specified\n"
308 " supported ops: fetch, store, delete\n",
309 opname);
310 goto done;
313 if (strcmp(keytype, "int32") == 0) {
314 type = TYPE_INT32;
315 value = (int32_t)strtol(valuestr, NULL, 10);
316 } else if (strcmp(keytype, "uint32") == 0) {
317 type = TYPE_UINT32;
318 value = (int32_t)strtoul(valuestr, NULL, 10);
319 } else {
320 d_fprintf(stderr, "ERROR: invalid type '%s' specified.\n"
321 " supported types: int32, uint32\n",
322 keytype);
323 goto done;
326 evt_ctx = tevent_context_init(mem_ctx);
327 if (evt_ctx == NULL) {
328 d_fprintf(stderr, "ERROR: could not init event context\n");
329 goto done;
332 msg_ctx = messaging_init(mem_ctx, procid_self(), evt_ctx);
333 if (msg_ctx == NULL) {
334 d_fprintf(stderr, "ERROR: could not init messaging context\n");
335 goto done;
338 db = db_open(mem_ctx, dbname, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644);
339 if (db == NULL) {
340 d_fprintf(stderr, "ERROR: could not open dbname\n");
341 goto done;
344 for (count = 0; dispatch_table[count].cmd != NULL; count++) {
345 if ((op == dispatch_table[count].op) &&
346 (type == dispatch_table[count].type))
348 ret = dispatch_table[count].cmd(db, keyname, &value);
349 break;
353 done:
354 TALLOC_FREE(mem_ctx);
355 return ret;