sub _open_file { my($file_name,$mode) = @_; $mode = "r" if(!defined($mode)); my $compress = 1; $compress = "" if($file_name =~ /\.xml$/i); if($mode eq "r") { my $fh = new IO::File($file_name); binmode $fh; my $f1 = ""; while(!$fh->eof()) { my $c = $fh->read($f1,1024*16,length($f1)); } $fh = undef; my $f2 = ""; if(defined($model_passphrase) && $model_passphrase ne "") { # Pad $f1 to the next 8 byte boundary if((length($f1) % 8) != 0) { $f1 .= "\x00" x (8 - (length($f1) % 8)); } my $cipher = new Crypt::Blowfish $model_passphrase; for(my $i=0;(8*$i)decrypt(substr($f1,8*$i,8)); } $f2 =~ s/\x00+$//s; } else { $f2 = $f1; } # Just in case the file is big save some memory $f1 = ""; my $f3 = ""; if($compress) { $f3 = uncompress($f2); } else { $f3 = $f2; } return new IO::Scalar \$f3; } else { # When writing I want to first get the output, then compress # then encrypt, then write to the file. # So I have to create a handle that does some magic # when it is closed my $buffer; return new IO::ActionOnClose(\$buffer, action => \&_send_file, args => [\$buffer,$file_name,$compress,$model_passphrase]); } } } sub _send_file { my($f3_ref,$file_name,$compress,$model_passphrase) = @_; # This is the reverse of what _open_file does for # read (even the variable names are the same) my $f2; if($compress) { $f2 = compress(${$f3_ref}); } else { $f2 = ${$f3_ref}; } my $f1 = ""; if(defined($model_passphrase) && $model_passphrase ne "") { my $cipher = new Crypt::Blowfish $model_passphrase; # Pad $f1 to the next 8 byte boundary if((length($f2) % 8) != 0) { $f2 .= "\x00" x (8 - (length($f2) % 8)); } for(my $i=0;8*$iencrypt(substr($f2,8*$i,8)); } } else { $f1 = $f2; } my $fh = new IO::File($file_name,"w"); binmode $fh; $fh->syswrite($f1,length($f1)); $fh->close(); }