2 Unix SMB/CIFS implementation.
3 Samba database functions
4 Copyright (C) Andrew Tridgell 1999-2000
5 Copyright (C) Paul `Rusty' Russell 2000
6 Copyright (C) Jeremy Allison 2000
7 Copyright (C) Andrew Esh 2001
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
40 /* a tdb tool for manipulating a tdb database */
42 #define FSTRING_LEN 256
43 typedef char fstring[FSTRING_LEN];
45 typedef struct connections_key {
51 typedef struct connections_data {
63 static struct tdb_context *tdb;
65 static int print_rec(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state);
67 static void print_asc(unsigned char *buf,int len)
71 /* We're probably printing ASCII strings so don't try to display
72 the trailing NULL character. */
74 if (buf[len - 1] == 0)
78 printf("%c",isprint(buf[i])?buf[i]:'.');
81 #ifdef PRINTF_ATTRIBUTE
82 static void tdb_log(struct tdb_context *t, int level, const char *format, ...) PRINTF_ATTRIBUTE(3,4);
84 static void tdb_log(struct tdb_context *t, int level, const char *format, ...)
89 vfprintf(stdout, format, ap);
94 static void print_data(unsigned char *buf,int len)
100 printf("%02X ",(int)buf[i]);
102 if (i%8 == 0) printf(" ");
104 print_asc(&buf[i-16],8); printf(" ");
105 print_asc(&buf[i-8],8); printf("\n");
106 if (i<len) printf("[%03X] ",i);
114 if (n>8) printf(" ");
115 while (n--) printf(" ");
119 print_asc(&buf[i-(i%16)],n); printf(" ");
121 if (n>0) print_asc(&buf[i-n],n);
126 static void help(void)
130 " create dbname : create a database\n"
131 " open dbname : open an existing database\n"
132 " erase : erase the database\n"
133 " dump : dump the database as strings\n"
134 " insert key data : insert a record\n"
135 " move key file : move a record to a destination tdb\n"
136 " store key data : store a record (replace)\n"
137 " show key : show a record by key\n"
138 " delete key : delete a record by key\n"
139 " list : print the database hash table and freelist\n"
140 " free : print the database freelist\n"
141 " 1 | first : print the first record\n"
142 " n | next : print the next record\n"
143 " q | quit : terminate\n"
144 " \\n : repeat 'next' command\n"
148 static void terror(const char *why)
153 static char *get_token(int startover)
155 static char tmp[1024];
156 static char *cont = NULL;
157 char *insert, *start;
158 char *k = strtok(NULL, " ");
169 insert = start + strlen(start) - 1;
170 while (*insert == '\\') {
172 k = strtok(NULL, " ");
176 insert = start + strlen(start) - 1;
179 /* Get ready for next call */
180 cont = start + strlen(start) + 1;
184 static void create_tdb(void)
186 char *tok = get_token(1);
191 if (tdb) tdb_close(tdb);
192 tdb = tdb_open_ex(tok, 0, TDB_CLEAR_IF_FIRST,
193 O_RDWR | O_CREAT | O_TRUNC, 0600, tdb_log, NULL);
195 printf("Could not create %s: %s\n", tok, strerror(errno));
199 static void open_tdb(void)
201 char *tok = get_token(1);
206 if (tdb) tdb_close(tdb);
207 tdb = tdb_open_ex(tok, 0, 0, O_RDWR, 0600, tdb_log, NULL);
209 printf("Could not open %s: %s\n", tok, strerror(errno));
213 static void insert_tdb(void)
215 char *k = get_token(1);
216 char *d = get_token(0);
224 key.dptr = (unsigned char *)k;
225 key.dsize = strlen(k)+1;
226 dbuf.dptr = (unsigned char *)d;
227 dbuf.dsize = strlen(d)+1;
229 if (tdb_store(tdb, key, dbuf, TDB_INSERT) == -1) {
230 terror("insert failed");
234 static void store_tdb(void)
236 char *k = get_token(1);
237 char *d = get_token(0);
245 key.dptr = (unsigned char *)k;
246 key.dsize = strlen(k)+1;
247 dbuf.dptr = (unsigned char *)d;
248 dbuf.dsize = strlen(d)+1;
250 printf("Storing key:\n");
251 print_rec(tdb, key, dbuf, NULL);
253 if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) {
254 terror("store failed");
258 static void show_tdb(void)
260 char *k = get_token(1);
268 key.dptr = (unsigned char *)k;
269 key.dsize = strlen(k)+1;
271 dbuf = tdb_fetch(tdb, key);
273 /* maybe it is non-NULL terminated key? */
274 key.dsize = strlen(k);
275 dbuf = tdb_fetch(tdb, key);
278 terror("fetch failed");
283 /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */
284 print_rec(tdb, key, dbuf, NULL);
291 static void delete_tdb(void)
293 char *k = get_token(1);
301 key.dptr = (unsigned char *)k;
302 key.dsize = strlen(k)+1;
304 if (tdb_delete(tdb, key) != 0) {
305 terror("delete failed");
309 static void move_rec(void)
311 char *k = get_token(1);
312 char *file = get_token(0);
314 struct tdb_context *dst_tdb;
322 terror("need destination tdb name");
326 key.dptr = (unsigned char *)k;
327 key.dsize = strlen(k)+1;
329 dbuf = tdb_fetch(tdb, key);
331 /* maybe it is non-NULL terminated key? */
332 key.dsize = strlen(k);
333 dbuf = tdb_fetch(tdb, key);
336 terror("fetch failed");
341 print_rec(tdb, key, dbuf, NULL);
343 dst_tdb = tdb_open_ex(file, 0, 0, O_RDWR, 0600, tdb_log, NULL);
345 terror("unable to open destination tdb");
349 if ( tdb_store( dst_tdb, key, dbuf, TDB_REPLACE ) == -1 ) {
350 terror("failed to move record");
353 printf("record moved\n");
355 tdb_close( dst_tdb );
360 static int print_rec(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
362 printf("\nkey %d bytes\n", key.dsize);
363 print_asc(key.dptr, key.dsize);
364 printf("\ndata %d bytes\n", dbuf.dsize);
365 print_data(dbuf.dptr, dbuf.dsize);
369 static int print_key(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
371 print_asc(key.dptr, key.dsize);
376 static int total_bytes;
378 static int traverse_fn(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
380 total_bytes += dbuf.dsize;
384 static void info_tdb(void)
388 if ((count = tdb_traverse(tdb, traverse_fn, NULL) == -1))
389 printf("Error = %s\n", tdb_errorstr(tdb));
391 printf("%d records totalling %d bytes\n", count, total_bytes);
394 static char *tdb_getline(const char *prompt)
396 static char line[1024];
398 fputs(prompt, stdout);
400 p = fgets(line, sizeof(line)-1, stdin);
401 if (p) p = strchr(p, '\n');
406 static int do_delete_fn(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf,
409 return tdb_delete(the_tdb, key);
412 static void first_record(struct tdb_context *the_tdb, TDB_DATA *pkey)
415 *pkey = tdb_firstkey(the_tdb);
417 dbuf = tdb_fetch(the_tdb, *pkey);
418 if (!dbuf.dptr) terror("fetch failed");
420 /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */
421 print_rec(the_tdb, *pkey, dbuf, NULL);
425 static void next_record(struct tdb_context *the_tdb, TDB_DATA *pkey)
428 *pkey = tdb_nextkey(the_tdb, *pkey);
430 dbuf = tdb_fetch(the_tdb, *pkey);
432 terror("fetch failed");
434 /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */
435 print_rec(the_tdb, *pkey, dbuf, NULL);
438 int main(int argc, char *argv[])
443 TDB_DATA iterate_kbuf;
446 static char tmp[1024];
447 sprintf(tmp, "open %s", argv[1]);
452 while ((line = tdb_getline("tdb> "))) {
456 if (line[0] == '!') {
461 if ((tok = strtok(line," "))==NULL) {
463 next_record(tdb, &iterate_kbuf);
466 if (strcmp(tok,"create") == 0) {
470 } else if (strcmp(tok,"open") == 0) {
473 } else if ((strcmp(tok, "q") == 0) ||
474 (strcmp(tok, "quit") == 0)) {
478 /* all the rest require a open database */
481 terror("database not open");
486 if (strcmp(tok,"insert") == 0) {
489 } else if (strcmp(tok,"store") == 0) {
492 } else if (strcmp(tok,"show") == 0) {
495 } else if (strcmp(tok,"erase") == 0) {
497 tdb_traverse(tdb, do_delete_fn, NULL);
498 } else if (strcmp(tok,"delete") == 0) {
501 } else if (strcmp(tok,"dump") == 0) {
503 tdb_traverse(tdb, print_rec, NULL);
504 } else if (strcmp(tok,"move") == 0) {
507 } else if (strcmp(tok,"list") == 0) {
509 } else if (strcmp(tok, "free") == 0) {
510 tdb_printfreelist(tdb);
511 } else if (strcmp(tok,"info") == 0) {
513 } else if ( (strcmp(tok, "1") == 0) ||
514 (strcmp(tok, "first") == 0)) {
516 first_record(tdb, &iterate_kbuf);
517 } else if ((strcmp(tok, "n") == 0) ||
518 (strcmp(tok, "next") == 0)) {
519 next_record(tdb, &iterate_kbuf);
520 } else if ((strcmp(tok, "keys") == 0)) {
522 tdb_traverse(tdb, print_key, NULL);
528 if (tdb) tdb_close(tdb);