Net-OpenSSH-More

 view release on metacpan or  search on metacpan

lib/Net/OpenSSH/More.pm  view on Meta::CPAN

sub diag {
    my ( $self, @msgs ) = @_;
    print STDOUT "$self->{'_opts'}{'output_prefix'}$_\n" for @msgs;
    return;
}


sub cmd {
    my ($self)  = shift;
    my $opts    = ref $_[0] eq 'HASH' ? shift : {};
    my @command = @_;

    $die_no_trace->( 'No command specified', 'PEBCAK' ) if !@command;

    my $ret;
    $opts->{'use_persistent_shell'} = $self->{'_opts'}{'use_persistent_shell'} if !exists $opts->{'use_persistent_shell'};
    if ( $opts->{'use_persistent_shell'} ) {
        $ret = $do_persistent_command->( $self, \@command, $opts->{'no_stderr'} );
    }
    else {
        $ret = $send->( $self, undef, @command );
    }
    chomp( my $out = $self->{'_out'} );
    my $err = $self->error || '';

    $self->{'last_exit_code'} = $ret;
    return ( $out, $err, $ret );
}


sub cmd_exit_code {
    my ( $self, @args ) = @_;
    return ( $self->cmd(@args) )[2];
}

sub sftp {
    my ($self) = @_;

    unless ( defined $self->{'_sftp'} ) {
        $self->{'_sftp'} = $self->SUPER::sftp();
        die 'Unable to establish SFTP connection to remote host: ' . $self->error() unless defined $self->{'_sftp'};
    }
    return $self->{'_sftp'};
}


sub write {
    my ( $self, $file, $content, $mode, $owner, $group ) = @_;

    die '[PARAMETER] No file specified'          if !defined $file;
    die '[PARAMETER] File content not specified' if !defined $content;

    my %opts;
    $opts{'perm'} = $mode if $mode;
    my $ret = $self->sftp()->put_content( $content, $file, %opts );
    warn "[WARN] Write failed: " . $self->sftp()->error() if !$ret;

    if ( defined $owner || defined $group ) {
        $owner //= $self->{'_opts'}{'user'};
        $group //= $owner;
        $ret = $self->sftp()->chown( $file, $owner, $group );
        warn "[WARN] Couldn't chown $file" if $ret;
    }

    return $ret;
}


sub eval_full {
    my ( $self, %options ) = @_;
    my $code = $options{code};
    my $args = $options{args} // [];
    my $exe  = $options{exe} || '/usr/bin/perl';

    require Storable;
    local $Storable::Deparse = 1;

    my ( $in_fh, $out_fh, undef, $pid ) = $call_ssh_reinit_if_check_fails->(
        $self,
        'open_ex',
        { stdin_pipe => 1, stdout_pipe => 1, stderr_to_stdout => 1 },
        q{export PERLCODE='use Storable;$Storable::Eval=1;my $input;while ($input .= <STDIN>) { if ($input =~ /\d+START_STORABLE(.*)STOP_STORABLE\d+/) { my @result = eval { my $in_hr = Storable::thaw(pack("H*", $1)); if ( ref $in_hr->{code} ) { retur...
          . $exe
          . q{ -e "$PERLCODE";}
    );

    die "Failed to connect: $!" unless ($pid);
    print $in_fh $$ . "START_STORABLE" . unpack( "H*", Storable::freeze( { code => $code, args => $args, wantarray => wantarray() } ) ) . "STOP_STORABLE" . $$ . "\n";
    close $in_fh;

    my $output = '';
    while ( $out_fh->sysread( $output, 4096, length($output) ) > 0 ) {
        1;
    }
    close $out_fh;
    waitpid( $pid, 0 );

    my $result = { error => "Unable to deserialize output from remote_eval: $output" };
    if ( $output =~ /\d+START_STORABLE(.*)STOP_STORABLE\d+/ ) {
        $result = Storable::thaw( pack( "H*", $1 ) );
    }

    die $result->{error} if ( $result->{error} );

    return wantarray ? @{ $result->{data} } : $result->{data}[0];
}


sub cmd_stream {
    my ( $self, @cmd ) = @_;
    my $line_reader = sub {
        my ( $self, $out, $stash_param ) = @_;
        $out =~ s/[\r\n]{1,2}$//;
        $self->diag($out);
        $self->{$stash_param} .= "$out\n";

        return;
    };
    return $send->( $self, $line_reader, @cmd );
}




( run in 2.139 seconds using v1.01-cache-2.11-cpan-71847e10f99 )