#!/usr/bin/perl -w

#
# A utility for listing/dumping the keys/values of squidGuardRobot DB files
#
# By Pl Baltzersen 1999-2000 (pal.baltzersen@ost.eltele.no)
#
# The current version may be found anytime at:
# http://ftp.ost.eltele.no/pub/www/proxy/squidGuard/contrib/squidGuardRobot/
#

# By accepting this notice, you agree to be bound by the following
# agreements:
# 
# This software product, squidGuardRobot, is copyrighted (C) 2000 by
# ElTele st AS, Oslo, Norway, with all rights reserved.
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License (version 2) as
# published by the Free Software Foundation.  It is distributed in the
# hope that it will be useful, but WITHOUT ANY WARRANTY; without even
# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE.  See the GNU General Public License (GPL) for more details.
# 
# You should have received a copy of the GNU General Public License
# (GPL) along with this program.

use strict;
use DB_File;
use Getopt::Std;

my $progname = $0; $progname =~ s/.*\///;
my $count;

sub usage($) {
  my $exit = shift;
  print STDERR "Usage: $progname [-c|-a|-k|-v] file.db [...]\n";
  print STDERR "\t-c\tJust count the keys\n";
  print STDERR "\t-a\tlist the keys and values (the default)\n";
  print STDERR "\t-k\tlist the keys only\n";
  print STDERR "\t-v\tlist the values only\n";
  exit($exit);
}

my %opts;
my $keys = 1;
my $vals = 1;
getopts("achkv", \%opts) || usage(1);
if (defined($opts{h})) {
  usage(0);
}
if (defined($opts{a})) {
  $keys++;
  $vals++;
}
if (defined($opts{c})) {
  $count++;
}
if (defined($opts{k})) {
  $keys++;
  $vals=0;
}
if (defined($opts{v})) {
  $keys=0;
  $vals++;
}

foreach (@ARGV) {
  my (%db, $db, $status, $key, $val);
  die("$_: $!") unless(-f);
  $db = tie(%db, "DB_File", $_, O_RDONLY, 0664, $DB_BTREE) || die("$_: $!");
  if ($count) {
    my $n;
    $key = $val = 0;
    for ($status = $db->seq($key, $val, R_FIRST);
	 $status == 0;
	 $status = $db->seq($key, $val, R_NEXT)) {
      $n++;
    }
    printf "$_:\t%d\n", $n;
  } else {
    $key = $val = 0;
    for ($status = $db->seq($key, $val, R_FIRST);
	 $status == 0;
	 $status = $db->seq($key, $val, R_NEXT)) {
      if($keys && $vals) {
	$val = "" unless(defined($val));
	print "$key\t$val\n";
      } elsif ($keys) {
	print "$key\n";
      } elsif ($vals) {
	$val = "" unless(defined($val));
	print "$val\n";
      }
    }
  }
  undef($db);
  untie(%db);
}
