#!/usr/local/bin/perl -w # "Fake" tarsnap. # Written by Tim Bishop, 2009. use strict; # for the database stuff use Fcntl; use NDBM_File; use Getopt::Long; # where our database is (adjust to suit) my($dbdir) = "/home/tdb/tarsnap"; sub set_dbdir ($) { my($dir) = @_; $dbdir = $dir; } # global tie to dbm my(%db); # (re)open the database in read-only mode sub db_open_ro { &db_close; if(!-d $dbdir) { my($result) = mkdir($dbdir); return $result unless $result; } my($result) = tie(%db, 'NDBM_File', "$dbdir/archives", O_RDONLY|O_CREAT, 0600); return $result; } # (re)open the database in read/write mode sub db_open_rw { &db_close; if(!-d $dbdir) { my($result) = mkdir($dbdir); return $result unless $result; } my($result) = tie(%db, 'NDBM_File', "$dbdir/archives", O_RDWR|O_CREAT, 0600); return $result; } # close the database sub db_close { my($result) = untie %db; return $result; } # put an entry into the database sub db_put ($) { my($archive) = @_; # switch to read/write unless(&db_open_rw) { return 0; } # write out the new data $db{$archive} = 1; # switch back to read-only unless(&db_open_ro) { return 0; } return 1; } # get an entry out of the database sub db_get ($) { my($archive) = @_; return $db{$archive}; } # get a list of all archives in the database sub db_get_all { return keys %db; } # delete an entry from the database sub db_delete ($) { my($archive) = @_; # switch to read/write unless(&db_open_rw) { return 0; } delete $db{$archive}; # switch back to read-only unless(&db_open_ro) { return 0; } return 1; } # checks if an entry is in the database sub db_check ($) { my($archive) = @_; return defined $db{$archive}; } my(@options) = ( "c", "d", "f=s", "list-archives", "lowmem", ); my $chosen = {}; unless (GetOptions ($chosen, @options)) { die("GetOptions failed"); } my $archive = $chosen->{f}; db_open_ro(); if(exists $chosen->{"list-archives"}) { my @archives = db_get_all(); foreach my $a (sort @archives) { print "$a\n"; } } elsif(exists $chosen->{"c"}) { die("No archive given") if not defined $archive; die("Already exists") if db_check($archive); db_put($archive); } elsif(exists $chosen->{"d"}) { die("No archive given") if not defined $archive; die("Doesn't exist") unless db_check($archive); db_delete($archive); } else { die("No options"); } db_close();