#!/usr/bin/perl
$^W=1;
use strict;
no utf8;
$ENV{LC_ALL}='C';

# vi(1) se: tabstop=4

# OTP (XOR) encrypt STDIN,
# first argument is used as OTP file or default of /dev/random
# and writing results to STDOUT.
# OTP data used (to length of STDIN) is written to second argument if
# present.

use File::Basename;

my $progname=basename($0);

$#ARGV <= 1 or
	die "usage: $progname [OTP_infile] [OTP_outfile]\n";

my $otp_infile;
if($#ARGV>=0){
	$otp_infile=$ARGV[0];
}else{
	$otp_infile='/dev/random';
};
open(OTP_INFILE,'<',$otp_infile) or
	die "$progname: failed to open $otp_infile: $!, aborting\n";

my $otp_outfile;
if($#ARGV==1){
	$otp_outfile=$ARGV[1];
	open(OTP_OUTFILE,'>',$otp_outfile) or
		die "$progname: failed to open $otp_outfile: $!, aborting\n";
};

{
	local $/=\1;
	local $_;
	my $o;
	if(defined($otp_outfile)){
		while(<STDIN>){
			$o=<OTP_INFILE>;
			defined($o) or
				die "$progname: failed to read $otp_infile: $!, aborting\n";
			print STDOUT ("$_" ^ "$o") or
				die "$progname: failed to write STDOUT: $!, aborting\n";
			print OTP_OUTFILE ($o) or
				die "$progname: failed to write $otp_outfile: $!, aborting\n";
		};
		close(OTP_OUTFILE) or
			die "$progname: failed to close $otp_outfile, aborting\n";
	}else{
		while(<STDIN>){
			$o=<OTP_INFILE>;
			defined($o) or
				die "$progname: failed to read $otp_infile: $!, aborting\n";
			print STDOUT ("$_" ^ "$o") or
				die "$progname: failed to write STDOUT: $!, aborting\n";
		};
	};
	close(OTP_INFILE) or
		die "$progname: failed to close $otp_infile, aborting\n";
};
