The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

package File::Slurp::Remote::SmartOpen;

use strict;
use warnings;
require Exporter;
use File::Slurp::Remote::BrokenDNS qw($myfqdn %fqdnify);
use Tie::Function::Examples qw(%q_shell);
use Carp qw(confess);

our @EXPORT = qw(smartopen);
our @ISA = qw(Exporter);
our $ssh = "ssh -o StrictHostKeyChecking=no -o BatchMode=yes -o PasswordAuthentication=no";
our $VERSION = 0.2;

sub smartopen($\$$)
{
	my ($file, $fdref, $mode) = @_;

	my $unzip = '';
	my $zip = '';
	if ($file =~ /\.gz$/) {
		$unzip = "zcat";
		$zip = "gzip";
	} elsif ($file =~ /\.bz2$/) {
		$unzip = "bzcat";
		$zip = "bzip2";
	}

	my $pid;

	my $fd = $$fdref;

	if ($file =~ s/(.+):// && $fqdnify{$1} ne $myfqdn) {
		my $host = $1;
		$unzip = "|$unzip" if $unzip;
		$zip = "$zip|" if $zip;
		if ($mode && $mode eq 'w') {
			my $cat = $q_shell{"cat > $q_shell{$file}"};
			$pid = open $fd, "|$zip $ssh $q_shell{$host} $cat"
				or confess "open |$zip $ssh $q_shell{$host} $cat: $!";
		} else {
			$pid = open $fd, "$ssh -n $q_shell{$host} cat $q_shell{$file} $unzip|"
				or confess "open $ssh $q_shell{$host} cat $q_shell{$file} $unzip|: $!";
		}
	} else {
		if ($mode && $mode eq 'w') {
			if ($zip) {
				$pid = open $fd, "|$zip > $q_shell{$file}"
					or die "open |$zip > $q_shell{$file}: $!";
			} else {
				open $fd, ">", $file
					or die "open >$file: $!";
				$pid = "0butTrue";
			}
		} else {
			if ($unzip) {
				$pid = open $fd, "$unzip < $q_shell{$file}|"
					or die "open $unzip < $q_shell{$file}|: $!";
			} else {
				open $fd, "<", $file
					or die "open <$file: $!";
				$pid = "0buttrue";
			}
		}
	}
	$$fdref = $fd;
	return $pid;
}

1;

__END__

=head1 NAME

File::Slurp::Remote::SmartOpen - open files locally or remotely automatially

=head1 SYNOPSIS

 use File::Slurp::Remote::SmartOpen;

 smartopen($file, $fd, $mode);

=head1 DESCRIPTION

This module provides one function: C<smartopen($file, $fd, $mode)>.
The function looks at the filename.  If it has a colon in it, then
it assumes that what comes before the colon is a hostname.  If that
hostname is not the hostname of the local system, it uses ssh 
to get to the remote system to open the file.

If the filename ends with C<.gz> or C<.bz2>, then it will pipe the
input (or output) though C<zcat> or C<bzcat> (C<gzip> or C<bzip2>) as
it opens the file.

The mode can be C<r> or C<w>.  It defaults to read.

By default, remote files are accessed with

 ssh -o StrictHostKeyChecking=no

You can override that by redefining C<$File::Slurp::Remote::SmartOpen::ssh>.

=head1 EXAMPLES

 smartopen("host1:/etc/passwd", my $fd, "r");

=head1 LICENSE

This package may be used and redistributed under the terms of either
the Artistic 2.0 or LGPL 2.1 license.