#################### main pod documentation begin ################### =head1 NAME Zymonic::Decryptor::Message::lftp - Zymonic Decryptor Message. =head1 SYNOPSIS This Message uses lftp to do remote file handling. =head1 DESCRIPTION This Message calls down to lftp to handle files on a remote location. It is used when sensitive data to do with the connection (e.g. password) are stored in the decryptor. =head1 USAGE The message should be: { messagetype => 'lftp', action => 'get' or 'put', host => ..., port => ..., username => ..., password => ..., protocol => ..., remote_directory => ..., accept => ..., # regex of filenames to accept ignore => ..., # regex of filenames to ignore # if get files => [...], # list of files to get, or all if none set local_directory => ..., # where to put them locally # if put files => [ ... ], # list of files to put in remote directory } The response will be: { error => ... } or ( if get ) { files => [ ... ] # list of files receieved } or ( if put ) { files=> [ ... ] # list of files sent } =head1 BUGS None we're aware of... =head1 SUPPORT As in the license, Zymonic is provided without warranty or support unless purchased separately, however... If you email zymonic-support@zednax.com your issue will be noted and may receive a response. For security issues, please contact zymonic-security@zednax.com and someone will respond within 8 working hours. =head1 AUTHOR Alex Masidlover et al. CPAN ID: MODAUTHOR Zednax Limited alex.masidlover@zednax.com http://www.zednax.com =head1 COPYRIGHT This program is free software licensed under the... Alfresco Public License 1.0 The full text of the license can be found in the LICENSE file included with this module. Other licenses may be acceptable if including parts of Zymonic in larger projects, please contact Zednax for details. =head1 SEE ALSO Zymonic::PaymentGateway perl(1). =cut #################### main pod documentation end ################### package Zymonic::Decryptor::Message::lftp; use strict; use warnings; BEGIN { use Exporter (); use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); $VERSION = '0.01'; @ISA = qw(Exporter); #Give a hoot don't pollute, do not export more than needed by default @EXPORT = qw(); @EXPORT_OK = qw(); %EXPORT_TAGS = (); } use base 'Zymonic::Decryptor::Message'; use Zymonic::Utils qw(clean); use Cwd qw(chdir getcwd); #################### subroutine header begin #################### =head2 respond Usage : my $response = $mh->repsond($in) Purpose : This is the response handler method for decryptor messages. Returns : a response hashref Argument : a message hashref Throws : nothing Comment : See Also : =cut #################### subroutine header end #################### sub respond { my $self = shift; my $in = shift; # check for required params map { return { error => "No lftp $_ specified." } unless $in->{$_}; } qw(action host username); $self->{decryptor_server}->connection_log("lftp $in->{action} Requested"); my $result = {}; my $ftp_cmd = "/usr/bin/lftp -u $in->{username}" . ( $in->{password} ? ',' . $in->{password} : '' ) . ' ' . ( $in->{port} ? '-p ' . $in->{port} . ' ' : '' ) . ' -e "debug off; %s; exit 0" ' . ( $in->{protocl} ? $in->{proctol} . '://' : '' ) . $in->{host} . '/'; if ( $in->{action} eq 'get' ) { return { error => "No lftp local_directory specified." } unless $in->{local_directory}; my @files = (); if ( ref( $in->{files} ) eq 'ARRAY' ) { @files = @{ $in->{files} }; } else { # lookup all files my $ls_cmd = sprintf( $ftp_cmd, 'ls -1' . ( $in->{remote_directory} ? ' ' . $in->{remote_directory} : '' ) ); @files = grep { ( $in->{accept} && $_ =~ /$in->{accept}/ ) || ( $in->{ignore} && $_ !~ /$in->{ignore}/ ) || ( !$in->{accept} && !$in->{ignore} ) } map { my $remote_filename = $_; # in case brings back a ls -l output, get name after date time $remote_filename = $1 if $remote_filename =~ /[a-z]{3} \d\d \d\d:\d\d (.*?)$/i; $remote_filename; } split( "\n", `$ls_cmd` ); } # return now if there are no files return { files => [] } unless @files; # move to tmp dir to copy files to return { error => "No such local directory: $in->{local_directory}" } unless -d $in->{local_directory}; my $cwd = clean( getcwd(), '/' ); chdir( $in->{local_directory} ); # get all files from location and remove them remotely my $get_cmd = sprintf( $ftp_cmd, join( '; ', map { 'get -E ' . $_ } @files ) ); my $res = system($get_cmd); # TODO: for some reason this list of get commands returns -1 return { error => "Error running command: $get_cmd\nReturned: $res" } unless $res <= 0; # switch dirs back chdir $cwd; return { files => [ map { $in->{local_directory} . '/' . $_ } @files ] }; } elsif ( $in->{action} eq 'put' ) { return { error => 'No files in lftp put command' } unless ref( $in->{files} ) eq 'ARRAY' && @{ $in->{files} }; my $put_cmd = sprintf( $ftp_cmd, ( $in->{remote_directory} ? 'cd ' . $in->{remote_directory} . '; ' : '' ) . join( '; ', map { 'put ' . $_ } @{ $in->{files} } ) ); my $res = system($put_cmd); # TODO: for some reason this list of get commands returns -1 return { error => "Error running command: $put_cmd\nReturned: $res" } unless $res <= 0; return { files => $in->{files} }; } else { return { error => 'Unknown lftp action ' . $in->{action} }; } return { error => 'Unable to complete lftp action ' . $in->{action} }; } 1;