bb11200ec4a305f2d9dcd669575e3bb5940cd0d4
[obnox/samba/samba-obnox.git] / lib / tdb / tools / tdbdump.c
1 /* 
2    Unix SMB/CIFS implementation.
3    simple tdb dump util
4    Copyright (C) Andrew Tridgell              2001
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "replace.h"
21 #include "system/locale.h"
22 #include "system/time.h"
23 #include "system/filesys.h"
24 #include "system/wait.h"
25 #include "tdb.h"
26
27 static void print_data(TDB_DATA d)
28 {
29         unsigned char *p = (unsigned char *)d.dptr;
30         int len = d.dsize;
31         while (len--) {
32                 if (isprint(*p) && !strchr("\"\\", *p)) {
33                         fputc(*p, stdout);
34                 } else {
35                         printf("\\%02X", *p);
36                 }
37                 p++;
38         }
39 }
40
41 static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
42 {
43         printf("{\n");
44         printf("key(%d) = \"", (int)key.dsize);
45         print_data(key);
46         printf("\"\n");
47         printf("data(%d) = \"", (int)dbuf.dsize);
48         print_data(dbuf);
49         printf("\"\n");
50         printf("}\n");
51         return 0;
52 }
53
54 static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level,
55                        const char *fmt, ...)
56 {
57         va_list ap;
58         char *ptr = NULL;
59         int debuglevel = 0;
60         int ret;
61         const char *name = tdb_name(tdb);
62         const char *prefix = "";
63
64         if (!name)
65                 name = "unnamed";
66
67         switch (level) {
68         case TDB_DEBUG_ERROR:
69                 prefix = "ERROR: ";
70                 break;
71         case TDB_DEBUG_WARNING:
72                 prefix = "WARNING: ";
73                 break;
74         case TDB_DEBUG_TRACE:
75                 return;
76
77         default:
78         case TDB_DEBUG_FATAL:
79                 prefix = "FATAL: ";
80                 break;
81         }
82
83         va_start(ap, fmt);
84         fprintf(stderr, "tdb(%s): %s", name, prefix);
85         vfprintf(stderr, fmt, ap);
86         va_end(ap);
87 }
88
89 static int dump_tdb(const char *fname, const char *keyname)
90 {
91         TDB_CONTEXT *tdb;
92         TDB_DATA key, value;
93         struct tdb_logging_context logfn = { log_stderr };
94         
95         tdb = tdb_open_ex(fname, 0, 0, O_RDONLY, 0, &logfn, NULL);
96         if (!tdb) {
97                 printf("Failed to open %s\n", fname);
98                 return 1;
99         }
100
101         if (!keyname) {
102                 return tdb_traverse(tdb, traverse_fn, NULL) == -1 ? 1 : 0;
103         } else {
104                 key.dptr = discard_const_p(uint8_t, keyname);
105                 key.dsize = strlen(keyname);
106                 value = tdb_fetch(tdb, key);
107                 if (!value.dptr) {
108                         return 1;
109                 } else {
110                         print_data(value);
111                         free(value.dptr);
112                 }
113         }
114
115         return 0;
116 }
117
118 static void usage( void)
119 {
120         printf( "Usage: tdbdump [options] <filename>\n\n");
121         printf( "   -h          this help message\n");
122         printf( "   -k keyname  dumps value of keyname\n");
123 }
124
125  int main(int argc, char *argv[])
126 {
127         char *fname, *keyname=NULL;
128         int c;
129
130         if (argc < 2) {
131                 printf("Usage: tdbdump <fname>\n");
132                 exit(1);
133         }
134
135         while ((c = getopt( argc, argv, "hk:")) != -1) {
136                 switch (c) {
137                 case 'h':
138                         usage();
139                         exit( 0);
140                 case 'k':
141                         keyname = optarg;
142                         break;
143                 default:
144                         usage();
145                         exit( 1);
146                 }
147         }
148
149         fname = argv[optind];
150
151         return dump_tdb(fname, keyname);
152 }