tdb: add -e option to tdbdump (and docment it).
[kai/samba.git] / lib / tdb / tools / tdbdump.c
index bb11200ec4a305f2d9dcd669575e3bb5940cd0d4..bcd395fd5afe0633f12308a6bdca17d054050356 100644 (file)
@@ -86,7 +86,18 @@ static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level,
        va_end(ap);
 }
 
-static int dump_tdb(const char *fname, const char *keyname)
+static void emergency_walk(TDB_DATA key, TDB_DATA dbuf, void *keyname)
+{
+       if (keyname) {
+               if (key.dsize != strlen(keyname))
+                       return;
+               if (memcmp(key.dptr, keyname, key.dsize) != 0)
+                       return;
+       }
+       traverse_fn(NULL, key, dbuf, NULL);
+}
+
+static int dump_tdb(const char *fname, const char *keyname, bool emergency)
 {
        TDB_CONTEXT *tdb;
        TDB_DATA key, value;
@@ -98,6 +109,9 @@ static int dump_tdb(const char *fname, const char *keyname)
                return 1;
        }
 
+       if (emergency) {
+               return tdb_rescue(tdb, emergency_walk, keyname) == 0;
+       }
        if (!keyname) {
                return tdb_traverse(tdb, traverse_fn, NULL) == -1 ? 1 : 0;
        } else {
@@ -120,11 +134,13 @@ static void usage( void)
        printf( "Usage: tdbdump [options] <filename>\n\n");
        printf( "   -h          this help message\n");
        printf( "   -k keyname  dumps value of keyname\n");
+       printf( "   -e          emergency dump, for corrupt databases\n");
 }
 
  int main(int argc, char *argv[])
 {
        char *fname, *keyname=NULL;
+       bool emergency = false;
        int c;
 
        if (argc < 2) {
@@ -132,7 +148,7 @@ static void usage( void)
                exit(1);
        }
 
-       while ((c = getopt( argc, argv, "hk:")) != -1) {
+       while ((c = getopt( argc, argv, "hk:e")) != -1) {
                switch (c) {
                case 'h':
                        usage();
@@ -140,6 +156,9 @@ static void usage( void)
                case 'k':
                        keyname = optarg;
                        break;
+               case 'e':
+                       emergency = true;
+                       break;
                default:
                        usage();
                        exit( 1);
@@ -148,5 +167,5 @@ static void usage( void)
 
        fname = argv[optind];
 
-       return dump_tdb(fname, keyname);
+       return dump_tdb(fname, keyname, emergency);
 }