#!/usr/bin/perl -w
#
# $Revision: 1.3 $ $Date: 2012-07-26 17:11:47-04 $
# $Source: /home/vogelke/bin/RCS/dbinfo,v $
# $Host: sys7.com $
# $UUID: ad267830-e233-3a94-8c26-53fbeecc855f $
#
#<dbinfo: identify berkeley DB version used to create a database file
# Author:       Paul Marquess  <Paul.Marquess@btinternet.com>
# Version:      1.05
# Date          1sh November 2003
#
# Copyright (c) 1998-2003 Paul Marquess. All rights reserved.
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.

# Todo: Print more stats on a db file, e.g. no of records
#       add log/txn/lock files

use strict;

my %Data = (
    0x053162 => {
        Type     => "Btree",
        Versions => {
            1 => [0, "Unknown (older than 1.71)"],
            2 => [0, "Unknown (older than 1.71)"],
            3 => [0, "1.71 -> 1.85, 1.86"],
            4 => [0, "Unknown"],
            5 => [0, "2.0.0 -> 2.3.0"],
            6 => [0, "2.3.1 -> 2.7.7"],
            7 => [0, "3.0.x"],
            8 => [0, "3.1.x -> 4.0.x"],
            9 => [1, "4.1.x or greater"],
          }
      },
    0x061561 => {
        Type     => "Hash",
        Versions => {
            1 => [0, "Unknown (older than 1.71)"],
            2 => [0, "1.71 -> 1.85"],
            3 => [0, "1.86"],
            4 => [0, "2.0.0 -> 2.1.0"],
            5 => [0, "2.2.6 -> 2.7.7"],
            6 => [0, "3.0.x"],
            7 => [0, "3.1.x -> 4.0.x"],
            8 => [1, "4.1.x or greater"],
          }
      },
    0x042253 => {
        Type     => "Queue",
        Versions => {
            1 => [0, "3.0.x"],
            2 => [0, "3.1.x"],
            3 => [0, "3.2.x -> 4.0.x"],
            4 => [1, "4.1.x or greater"],
          }
      },
      );

die "Usage: dbinfo file\n" unless @ARGV == 1;

print "testing file $ARGV[0]...\n\n";
my $fh;
open($fh, "<$ARGV[0]") or die "Cannot open file $ARGV[0]: $!\n";

my $buff;
read $fh, $buff, 30;

my (@info)  = unpack("NNNNNNC", $buff);
my (@info1) = unpack("VVVVVVC", $buff);
my ($magic, $version, $endian, $encrypt);

if ($Data{$info[0]})    # first try DB 1.x format, big endian
{
    $magic   = $info[0];
    $version = $info[1];
    $endian  = "Big Endian";
    $encrypt = "Not Supported";
}
elsif ($Data{$info1[0]})    # first try DB 1.x format, little endian
{
    $magic   = $info1[0];
    $version = $info1[1];
    $endian  = "Little Endian";
    $encrypt = "Not Supported";
}
elsif ($Data{$info[3]})     # next DB 2.x big endian
{
    $magic   = $info[3];
    $version = $info[4];
    $endian  = "Big Endian";
}
elsif ($Data{$info1[3]})    # next DB 2.x little endian
{
    $magic   = $info1[3];
    $version = $info1[4];
    $endian  = "Little Endian";
}
else { die "not a Berkeley DB database file.\n" }

my $type = $Data{$magic};
$magic = sprintf "%06X", $magic;

my $ver_string = "Unknown";

if (defined $type->{Versions}{$version}) {
    $ver_string = $type->{Versions}{$version}[1];
    if ($type->{Versions}{$version}[0]) {
        $encrypt = $info[6] ? "Enabled" : "Disabled";
    }
    else { $encrypt = "Not Supported" }
}

print <<EOM ;
File Type:              Berkeley DB $type->{Type} file.
File Version ID:        $version
Built with Berkeley DB: $ver_string
Byte Order:             $endian
Magic:                  $magic
Encryption:             $encrypt
EOM

close $fh;
exit(0);
