• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.5.8/source3/utils/
1/*
2   Samba Unix/Linux CIFS implementation
3
4   low level TDB/CTDB tool using the dbwrap interface
5
6   Copyright (C) 2009 Michael Adam <obnox@samba.org>
7
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.
12
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.
17
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/>.
20*/
21
22#include "includes.h"
23
24extern bool AllowDebugChange;
25
26typedef enum { OP_FETCH, OP_STORE, OP_DELETE, OP_ERASE, OP_LISTKEYS } dbwrap_op;
27
28typedef enum { TYPE_INT32, TYPE_UINT32 } dbwrap_type;
29
30static int dbwrap_tool_fetch_int32(struct db_context *db,
31				   const char *keyname,
32				   void *data)
33{
34	int32_t value;
35
36	value = dbwrap_fetch_int32(db, keyname);
37	d_printf("%d\n", value);
38
39	return 0;
40}
41
42static int dbwrap_tool_fetch_uint32(struct db_context *db,
43				    const char *keyname,
44				    void *data)
45{
46	uint32_t value;
47	bool ret;
48
49	ret = dbwrap_fetch_uint32(db, keyname, &value);
50	if (ret) {
51		d_printf("%u\n", value);
52		return 0;
53	} else {
54		d_fprintf(stderr, "ERROR: could not fetch uint32 key '%s'\n",
55			  keyname);
56		return -1;
57	}
58}
59
60static int dbwrap_tool_store_int32(struct db_context *db,
61				   const char *keyname,
62				   void *data)
63{
64	NTSTATUS status;
65	int32_t value = *((int32_t *)data);
66
67	status = dbwrap_trans_store_int32(db, keyname, value);
68
69	if (!NT_STATUS_IS_OK(status)) {
70		d_fprintf(stderr, "ERROR: could not store int32 key '%s': %s\n",
71			  keyname, nt_errstr(status));
72		return -1;
73	}
74
75	return 0;
76}
77
78static int dbwrap_tool_store_uint32(struct db_context *db,
79				    const char *keyname,
80				    void *data)
81{
82	NTSTATUS status;
83	uint32_t value = *((uint32_t *)data);
84
85	status = dbwrap_trans_store_uint32(db, keyname, value);
86
87	if (!NT_STATUS_IS_OK(status)) {
88		d_fprintf(stderr,
89			  "ERROR: could not store uint32 key '%s': %s\n",
90			  keyname, nt_errstr(status));
91		return -1;
92	}
93
94	return 0;
95}
96
97static int dbwrap_tool_delete(struct db_context *db,
98			      const char *keyname,
99			      void *data)
100{
101	NTSTATUS status;
102
103	status = dbwrap_trans_delete_bystring(db, keyname);
104
105	if (!NT_STATUS_IS_OK(status)) {
106		d_fprintf(stderr, "ERROR deleting record %s : %s\n",
107			  keyname, nt_errstr(status));
108		return -1;
109	}
110
111	return 0;
112}
113
114static int delete_fn(struct db_record *rec, void *priv)
115{
116	rec->delete_rec(rec);
117	return 0;
118}
119
120/**
121 * dbwrap_tool_erase: erase the whole data base
122 * the keyname argument is not used.
123 */
124static int dbwrap_tool_erase(struct db_context *db,
125			     const char *keyname,
126			     void *data)
127{
128	int ret;
129
130	ret = db->traverse(db, delete_fn, NULL);
131
132	if (ret < 0) {
133		d_fprintf(stderr, "ERROR erasing the database\n");
134		return -1;
135	}
136
137	return 0;
138}
139
140static int listkey_fn(struct db_record *rec, void *private_data)
141{
142	int length = rec->key.dsize;
143	unsigned char *p = (unsigned char *)rec->key.dptr;
144
145	while (length--) {
146		if (isprint(*p) && !strchr("\"\\", *p)) {
147			d_printf("%c", *p);
148		} else {
149			d_printf("\\%02X", *p);
150		}
151		p++;
152	}
153
154	d_printf("\n");
155
156	return 0;
157}
158
159static int dbwrap_tool_listkeys(struct db_context *db,
160				const char *keyname,
161				void *data)
162{
163	int ret;
164
165	ret = db->traverse_read(db, listkey_fn, NULL);
166
167	if (ret < 0) {
168		d_fprintf(stderr, "ERROR listing db keys\n");
169		return -1;
170	}
171
172	return 0;
173}
174
175struct dbwrap_op_dispatch_table {
176	dbwrap_op op;
177	dbwrap_type type;
178	int (*cmd)(struct db_context *db,
179		   const char *keyname,
180		   void *data);
181};
182
183struct dbwrap_op_dispatch_table dispatch_table[] = {
184	{ OP_FETCH,  TYPE_INT32,  dbwrap_tool_fetch_int32 },
185	{ OP_FETCH,  TYPE_UINT32, dbwrap_tool_fetch_uint32 },
186	{ OP_STORE,  TYPE_INT32,  dbwrap_tool_store_int32 },
187	{ OP_STORE,  TYPE_UINT32, dbwrap_tool_store_uint32 },
188	{ OP_DELETE, TYPE_INT32,  dbwrap_tool_delete },
189	{ OP_ERASE,  TYPE_INT32,  dbwrap_tool_erase },
190	{ OP_LISTKEYS, TYPE_INT32, dbwrap_tool_listkeys },
191	{ 0, 0, NULL },
192};
193
194int main(int argc, const char **argv)
195{
196	struct tevent_context *evt_ctx;
197	struct messaging_context *msg_ctx;
198	struct db_context *db;
199
200	uint16_t count;
201
202	const char *dbname;
203	const char *opname;
204	dbwrap_op op;
205	const char *keyname = "";
206	const char *keytype = "int32";
207	dbwrap_type type;
208	const char *valuestr = "0";
209	int32_t value = 0;
210
211	TALLOC_CTX *mem_ctx = talloc_stackframe();
212
213	int ret = 1;
214
215	load_case_tables();
216	DEBUGLEVEL_CLASS[DBGC_ALL] = 0;
217	dbf = x_stderr;
218	AllowDebugChange = false;
219	lp_load(get_dyn_CONFIGFILE(), true, false, false, true);
220
221	if ((argc < 3) || (argc > 6)) {
222		d_fprintf(stderr,
223			  "USAGE: %s <database> <op> [<key> [<type> [<value>]]]\n"
224			  "       ops: fetch, store, delete, erase, listkeys\n"
225			  "       types: int32, uint32\n",
226			 argv[0]);
227		goto done;
228	}
229
230	dbname = argv[1];
231	opname = argv[2];
232
233	if (strcmp(opname, "store") == 0) {
234		if (argc != 6) {
235			d_fprintf(stderr, "ERROR: operation 'store' requires "
236				  "value argument\n");
237			goto done;
238		}
239		valuestr = argv[5];
240		keytype = argv[4];
241		keyname = argv[3];
242		op = OP_STORE;
243	} else if (strcmp(opname, "fetch") == 0) {
244		if (argc != 5) {
245			d_fprintf(stderr, "ERROR: operation 'fetch' requires "
246				  "type but not value argument\n");
247			goto done;
248		}
249		op = OP_FETCH;
250		keytype = argv[4];
251		keyname = argv[3];
252	} else if (strcmp(opname, "delete") == 0) {
253		if (argc != 4) {
254			d_fprintf(stderr, "ERROR: operation 'delete' does "
255				  "not allow type nor value argument\n");
256			goto done;
257		}
258		keyname = argv[3];
259		op = OP_DELETE;
260	} else if (strcmp(opname, "erase") == 0) {
261		if (argc != 3) {
262			d_fprintf(stderr, "ERROR: operation 'erase' does "
263				  "not take a key argument\n");
264			goto done;
265		}
266		op = OP_ERASE;
267	} else if (strcmp(opname, "listkeys") == 0) {
268		if (argc != 3) {
269			d_fprintf(stderr, "ERROR: operation 'listkeys' does "
270				  "not take a key argument\n");
271			goto done;
272		}
273		op = OP_LISTKEYS;
274	} else {
275		d_fprintf(stderr,
276			  "ERROR: invalid op '%s' specified\n"
277			  "       supported ops: fetch, store, delete\n",
278			  opname);
279		goto done;
280	}
281
282	if (strcmp(keytype, "int32") == 0) {
283		type = TYPE_INT32;
284		value = (int32_t)strtol(valuestr, NULL, 10);
285	} else if (strcmp(keytype, "uint32") == 0) {
286		type = TYPE_UINT32;
287		value = (int32_t)strtoul(valuestr, NULL, 10);
288	} else {
289		d_fprintf(stderr, "ERROR: invalid type '%s' specified.\n"
290				  "       supported types: int32, uint32\n",
291				  keytype);
292		goto done;
293	}
294
295	evt_ctx = tevent_context_init(mem_ctx);
296	if (evt_ctx == NULL) {
297		d_fprintf(stderr, "ERROR: could not init event context\n");
298		goto done;
299	}
300
301	msg_ctx = messaging_init(mem_ctx, server_id_self(), evt_ctx);
302	if (msg_ctx == NULL) {
303		d_fprintf(stderr, "ERROR: could not init messaging context\n");
304		goto done;
305	}
306
307	db = db_open(mem_ctx, dbname, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644);
308	if (db == NULL) {
309		d_fprintf(stderr, "ERROR: could not open dbname\n");
310		goto done;
311	}
312
313	for (count = 0; dispatch_table[count].cmd != NULL; count++) {
314		if ((op == dispatch_table[count].op) &&
315		    (type == dispatch_table[count].type))
316		{
317			ret = dispatch_table[count].cmd(db, keyname, &value);
318			break;
319		}
320	}
321
322done:
323	TALLOC_FREE(mem_ctx);
324	return ret;
325}
326