1# 2# (c) Jan Gehring <jan.gehring@gmail.com> 3# 4# vim: set ts=2 sw=2 tw=0: 5# vim: set expandtab: 6 7package Rex::Interface::Fs::Base; 8 9use 5.010001; 10use strict; 11use warnings; 12 13our $VERSION = '1.13.4'; # VERSION 14 15use English qw(-no_match_vars); 16use Rex::Interface::Exec; 17use Rex::Helper::File::Spec; 18 19sub new { 20 my $that = shift; 21 my $proto = ref($that) || $that; 22 my $self = {@_}; 23 24 bless( $self, $proto ); 25 26 return $self; 27} 28 29sub ls { die("Must be implemented by Interface Class"); } 30sub unlink { die("Must be implemented by Interface Class"); } 31sub mkdir { die("Must be implemented by Interface Class"); } 32sub glob { die("Must be implemented by Interface Class"); } 33sub rename { die("Must be implemented by Interface Class"); } 34sub stat { die("Must be implemented by Interface Class"); } 35sub readlink { die("Must be implemented by Interface Class"); } 36sub is_file { die("Must be implemented by Interface Class"); } 37sub is_dir { die("Must be implemented by Interface Class"); } 38sub is_readable { die("Must be implemented by Interface Class"); } 39sub is_writable { die("Must be implemented by Interface Class"); } 40sub upload { die("Must be implemented by Interface Class"); } 41sub download { die("Must be implemented by Interface Class"); } 42 43sub is_symlink { 44 my ( $self, $path ) = @_; 45 ($path) = $self->_normalize_path($path); 46 47 $self->_exec("/bin/sh -c '[ -L \"$path\" ]'"); 48 my $ret = $?; 49 50 if ( $ret == 0 ) { return 1; } 51} 52 53sub ln { 54 my ( $self, $from, $to ) = @_; 55 56 Rex::Logger::debug("Symlinking files: $to -> $from"); 57 ($from) = $self->_normalize_path($from); 58 ($to) = $self->_normalize_path($to); 59 60 my $exec = Rex::Interface::Exec->create; 61 $exec->exec("ln -snf $from $to"); 62 63 if ( $? == 0 ) { return 1; } 64 65 die "Error creating symlink. ($from -> $to)" if ( Rex::Config->get_autodie ); 66} 67 68sub rmdir { 69 my ( $self, @dirs ) = @_; 70 71 @dirs = $self->_normalize_path(@dirs); 72 73 Rex::Logger::debug( "Removing directories: " . join( ", ", @dirs ) ); 74 my $exec = Rex::Interface::Exec->create; 75 $exec->exec( "/bin/rm -rf " . join( " ", @dirs ) ); 76 77 if ( $? == 0 ) { return 1; } 78 79 die( "Error removing directory: " . join( ", ", @dirs ) ) 80 if ( Rex::Config->get_autodie ); 81} 82 83sub chown { 84 my ( $self, $user, $file, @opts ) = @_; 85 my $options = {@opts}; 86 ($file) = $self->_normalize_path($file); 87 88 my $recursive = ""; 89 if ( exists $options->{"recursive"} && $options->{"recursive"} == 1 ) { 90 $recursive = " -R "; 91 } 92 93 my $exec = Rex::Interface::Exec->create; 94 95 if ( $exec->can_run( ['chown'] ) ) { 96 $exec->exec("chown $recursive $user $file"); 97 98 if ( $? == 0 ) { return 1; } 99 100 die("Error running chown $recursive $user $file") 101 if ( Rex::Config->get_autodie ); 102 } 103 else { 104 Rex::Logger::debug("Can't find `chown`."); 105 return 1; # fake success for windows 106 } 107} 108 109sub chgrp { 110 my ( $self, $group, $file, @opts ) = @_; 111 my $options = {@opts}; 112 ($file) = $self->_normalize_path($file); 113 114 my $recursive = ""; 115 if ( exists $options->{"recursive"} && $options->{"recursive"} == 1 ) { 116 $recursive = " -R "; 117 } 118 119 my $exec = Rex::Interface::Exec->create; 120 121 if ( $exec->can_run( ['chgrp'] ) ) { 122 $exec->exec("chgrp $recursive $group $file"); 123 124 if ( $? == 0 ) { return 1; } 125 126 die("Error running chgrp $recursive $group $file") 127 if ( Rex::Config->get_autodie ); 128 } 129 else { 130 Rex::Logger::debug("Can't find `chgrp`."); 131 return 1; # fake success for windows 132 } 133} 134 135sub chmod { 136 my ( $self, $mode, $file, @opts ) = @_; 137 my $options = {@opts}; 138 ($file) = $self->_normalize_path($file); 139 140 my $recursive = ""; 141 if ( exists $options->{"recursive"} && $options->{"recursive"} == 1 ) { 142 $recursive = " -R "; 143 } 144 145 my $exec = Rex::Interface::Exec->create; 146 147 if ( $exec->can_run( ['chmod'] ) ) { 148 $exec->exec("chmod $recursive $mode $file"); 149 150 if ( $? == 0 ) { return 1; } 151 152 die("Error running chmod $recursive $mode $file") 153 if ( Rex::Config->get_autodie ); 154 } 155 else { 156 Rex::Logger::debug("Can't find `chmod`."); 157 return 1; # fake success for windows 158 } 159} 160 161sub cp { 162 my ( $self, $source, $dest ) = @_; 163 ($source) = $self->_normalize_path($source); 164 ($dest) = $self->_normalize_path($dest); 165 166 my $exec = Rex::Interface::Exec->create; 167 168 if ( $OSNAME =~ m/^MSWin/msx ) { 169 $exec->exec("copy /v /y $source $dest"); 170 } 171 else { 172 $exec->exec("cp -R $source $dest"); 173 } 174 175 if ( $? == 0 ) { return 1; } 176 177 die("Error copying $source -> $dest") if ( Rex::Config->get_autodie ); 178} 179 180sub _normalize_path { 181 my ( $self, @dirs ) = @_; 182 183 my @ret; 184 for my $d (@dirs) { 185 my @t; 186 if (Rex::is_ssh) { 187 @t = Rex::Helper::File::Spec->splitdir($d); 188 } 189 else { 190 @t = Rex::Helper::File::Spec->splitdir($d); 191 } 192 push( @ret, 193 Rex::Helper::File::Spec->catfile( map { $self->_quotepath($_) } @t ) ); 194 } 195 196 # for (@dirs) { 197 # s/ /\\ /g; 198 # } 199 200 return @ret; 201} 202 203sub _quotepath { 204 my ( $self, $p ) = @_; 205 $p =~ s/([\@\$\% ])/\\$1/g; 206 207 return $p; 208} 209 210sub _exec { 211 my ( $self, $cmd ) = @_; 212 my $exec = Rex::Interface::Exec->create; 213 return $exec->exec($cmd); 214} 215 2161; 217