#!/usr/bin/perl

#author: Vidul

use Crypt::Serpent;
use Getopt::Std;
use bytes;
use strict;

getopt('k:f:');
my($buffer,$key,$enc,$dec,$enc_f,$dec_f,@tmp);
die "do \`man Crypt::Serpent\`\nscript writer Vidul N.P.\n" if $main::opt_a;
die &usage unless (($main::opt_e || $main::opt_d) && $main::opt_k && $main::opt_f);
$key = _to16($main::opt_k);
die "wrong file name $main::opt_f\n" unless(-e $main::opt_f);
my $serpent = new Crypt::Serpent $key;
if($main::opt_e){
	open(FHR, "$main::opt_f");
	$enc_f = $main::opt_f;
	open(FHW, ">$enc_f.enc");
 	binmode(FHR);
	binmode(FHW);
	flock(FHR, 1);
	flock(FHW, 2);
	while(read FHR, $buffer, 16){
	  if(length($buffer) < 16)
		{ $buffer = pack "a16", $buffer; }
	  $enc = $serpent->encrypt($buffer);
	  print FHW $enc;
	  print STDOUT $enc if $main::opt_o;
	}
close(FHR);
close(FHW);
unlink("$main::opt_f") if $main::opt_r;
exit 0;
}
if($main::opt_d){
	open(FHR, "<$main::opt_f");
	($dec_f = $main::opt_f) =~ s/(\.\w+)$//;
	open(FHW, ">$dec_f");
	binmode(FHR);
	binmode(FHW);
	flock(FHR, 1);
	flock(FHW, 2);
	while(read FHR, $buffer, 16){
      	  unless((16 - length($buffer)) == 0){ $buffer .= ' ' x (16 - length($buffer)) }
	  $dec = $serpent->decrypt($buffer);	
	  push @tmp, $dec;
    }
for(@tmp){ 
	print STDOUT $_ and next if $main::opt_o;
	print FHW $_;
}
close(FHR);
close(FHW);
unlink("$dec_f.dec") if -z "$dec_f.dec";
unlink("$main::opt_f") if $main::opt_r;
exit 0;
}

sub _to16{
	my $digit = shift;
	return $digit if length$digit == 16;
 	if(length$digit > 16 && length$digit < 32){
		$digit = pack "a32", $digit;
		return $digit;
	} elsif(length$digit < 16 && length$digit > 0){
		$digit = pack "a16", $digit;
		return $digit;
	} else {
		print "wrong digit\n";
		die "\n"
	}
}
sub usage{
	print <<"SQ";
		(-e|-d) encrypt|decrypt
		(-k) key
		(-f) file
		[-r] removes working file
		[-o] prints to STDOUT
		[-a] Real author
SQ
	exit
}
