setbookmark.pl
#!/usr/bin/perl
use strict;
# Syntax: perl setbookmark.pl onetimepad_file new_bookmark
# This sets the value of the bookmark in the given one-time pad and erases the data
# between the old bookmark and the bookmark.
my $True = 1;
my $False = 0;
# Execution starts here
&main;
sub main()
{
my $intNumArgs = $#ARGV + 1;
if ($intNumArgs != 2)
{
print "Syntax: perl setbookmark.pl onetimepad_file new_bookmark\n";
exit 1;
}
# Read the arguments on the command line
my $strPadFilename = $ARGV[0];
my $lngNewBookmark = $ARGV[1];
my $lngCurrentBookmark = ReadBookmark($strPadFilename);
if ($lngCurrentBookmark == 0)
{
exit 1;
}
print "Current bookmark is ".$lngCurrentBookmark."\n";
if ($lngNewBookmark <= $lngCurrentBookmark)
{
print "ERROR:New bookmark must be set after current bookmark\n";
exit 1;
}
my $lngFileSize = -s $strPadFilename;
print "File size is ".$lngFileSize."\n";
if ($lngNewBookmark > $lngFileSize )
{
print "ERROR:New bookmark is beyond the end of the file\n";
exit 1;
}
if (SetBookmarkAndDeleteData($strPadFilename, $lngCurrentBookmark, $lngNewBookmark) == $False)
{
exit 1;
}
exit 0;
}
sub ReadBookmark($)
{
my $strPadFilename = $_[0];
if (!open PAD_FILE, "<$strPadFilename")
{
print "ERROR:Can't open file $strPadFilename\n";
return 0;
}
# Handle the file as bytes instead of text
binmode PAD_FILE;
my $lngBookmark = unpack('L', <PAD_FILE>);
close PAD_FILE;
return $lngBookmark;
}
sub SetBookmarkAndDeleteData($$$)
{
my $strPadFilename = $_[0];
my $lngCurrentBookmark = $_[1];
my $lngNewBookmark = $_[2];
if (!open PAD_FILE, "+<$strPadFilename")
{
print "ERROR:Can't open file $strPadFilename\n";
return $False;
}
# Handle the file as bytes instead of text
binmode PAD_FILE;
# Write the new bookmark at the start of the file
seek(PAD_FILE, 0, 0);
print PAD_FILE pack('L', $lngNewBookmark);
print "Bookmark updated to ".$lngNewBookmark."\n";
# Delete data between old and new bookmarks
seek(PAD_FILE, $lngCurrentBookmark, 0);
for(my $lngCounter = $lngCurrentBookmark; $lngCounter < $lngNewBookmark; $lngCounter++)
{
my $byte = 0;
print PAD_FILE pack('C', $byte);
}
print "Data up to new bookmark deleted\n";
close PAD_FILE;
return $True;
}
