#!/usr/bin/perl -w

use 5.008;
use strict;
use warnings;

use Fcntl;   # For O_RDWR, O_CREAT, etc.
use FreezeThaw;
use Data::Dumper;

my($key, $field, $values);
my $dbmType = "NDBM";

my $usage = "Usage: $0 [-g|-s] [-k <key> | -f <field> | -v] <ndbm-file>\n";
while (@ARGV >= 2) {
    if ($ARGV[0] eq "-g") {
	shift; $dbmType = "GDBM";
    } elsif ($ARGV[0] eq "-s") {
	shift; $dbmType = "SDBM";
    } elsif ($ARGV[0] eq "-k") {
	shift; $key = shift;
    } elsif ($ARGV[0] eq "-f") {
	shift; $field = shift;
    } elsif ($ARGV[0] eq "-v") {
	shift; $values = 1
    } elsif ($ARGV[0] =~ /^-/) {
	die $usage;
    } else {
	last
    }
}

require "${dbmType}_File.pm";

die $usage if @ARGV != 1;
my $dbfile = $ARGV[0];

my %h;
if (!tie(%h, "${dbmType}_File", $dbfile, O_RDONLY, 0666)) {
    die "Couldn't read $dbmType file '$dbfile': $!";
}

if ($key) {
    my $val = $h{$key};
    die "$0: no such entry '$key'" if !$val;
    my($session) = FreezeThaw::thaw($val);
    print Dumper($session);
} elsif ($field || $values) {
    foreach my $key (sort keys %h) {
	my $val = $h{$key};
	if ($values) {
	    print "$key:$val\n";
	} else {
	    my($session) = FreezeThaw::thaw($val);
	    print "$key:", ($session->{$field} || ""), "\n";
	}
    }
} else {
    print join("", map { "$_\n"  } sort keys %h);
}

untie %h;


=head1 NAME

ndbm-dump-sessions - simple tool for dumping contents of NDBM files

=head1 SYNOPSIS

ndbm-dump-sessions
[
-g
|
-s
]
[
-k
I<key>
]
[
-f
I<field>
]
[
-v
]
I<ndbm-file>

=head1 DESCRIPTION

C<ndbm-dump-sessions>
provides a simple tool for dumping the contents of an NDBM database,
such as is used by the MasterKey Admin Console to store persistent
session data.  Typical usage is as follows:

 $ ndbm-dump-sessions /tmp/mkadmin-sessions.ndbm
 +nPc0a7CeaNO
 8vwbJzk1bQpq
 cXlePvado0RQ
 zg2rImBqNYsD
 [...]
 $ ndbm-dump-sessions -k 8vwbJzk1bQpq /tmp/mkadmin-sessions.ndbm
 $VAR1 = bless( {
                  'dest' => '/searchable/',
                  'cookie' => '8vwbJzk1bQpq',
                  'user_id' => 'local-6'
                }, 'Masterkey::Admin::Session' );
 $ ndbm-dump-sessions -f user_id /tmp/mkadmin-sessions.ndbm
 +nPc0a7CeaNO:local-6
 8vwbJzk1bQpq:local-6
 cXlePvado0RQ:master-user.xml
 zg2rImBqNYsD:master-user.xml
 [...]

By default, it output the keys of the NDBM file only, one per line.

=head1 OPTIONS

=over 4

=item -g

Use GDBM rather than NDBM.

=item -s

Use SDBM rather than NDBM.

=item -k I<key>

Output the whole of the Perl objects stored under the specified I<key>
(which should be one of those output by running with no arguments).
Yes, this output is ugly -- it uses C<Data::Dumper>.  Does Perl have a
better pretty-printer in its standard library?

(Relies on the values being frozen Perl objects.)

=item -f I<field>

Output the value of the specified I<field> for each entry in the
database.

(Relies on the values being frozen Perl objects.)

=item -v

Output the raw values associated with each key.

(Does not rely on the values being frozen Perl objects.)

=back

=head1 AUTHOR

Copyright (C) 2008-2009 by Index Data Aps E<lt>info@indexdata.comE<gt>

=cut
