File Coverage

lib/Rex/Interface/File/Sudo.pm
Criterion Covered Total %
statement 23 76 30.2
branch 0 16 0.0
condition 0 12 0.0
subroutine 8 15 53.3
pod 0 6 0.0
total 31 125 24.8


line stmt bran cond sub pod time code
1             #
2             # (c) Jan Gehring
3             #
4              
5             package Rex::Interface::File::Sudo;
6              
7 1     1   13 use v5.12.5;
  1         4  
8 1     1   4 use warnings;
  1         2  
  1         51  
9              
10             our $VERSION = '1.14.3'; # VERSION
11              
12 1     1   10 use Fcntl;
  1         5  
  1         394  
13 1     1   10 use File::Basename;
  1         8  
  1         89  
14             require Rex::Commands;
15 1     1   16 use Rex::Interface::Fs;
  1         4  
  1         6  
16 1     1   46 use Rex::Interface::File::Base;
  1         7  
  1         32  
17 1     1   23 use Rex::Helper::Path;
  1         3  
  1         79  
18 1     1   15 use base qw(Rex::Interface::File::Base);
  1         2  
  1         1020  
19              
20             sub new {
21 0     0 0   my $that = shift;
22 0   0       my $proto = ref($that) || $that;
23 0           my $self = $proto->SUPER::new(@_);
24              
25 0           bless( $self, $proto );
26              
27 0           return $self;
28             }
29              
30             sub open {
31 0     0 0   my ( $self, $mode, $file ) = @_;
32              
33 0 0         if ( my $ssh = Rex::is_ssh() ) {
34 0 0         if ( ref $ssh eq "Net::OpenSSH" ) {
35 0           $self->{fh} = Rex::Interface::File->create("OpenSSH");
36             }
37             else {
38 0           $self->{fh} = Rex::Interface::File->create("SSH");
39             }
40             }
41             else {
42 0           $self->{fh} = Rex::Interface::File->create("Local");
43             }
44              
45             # always use current logged in user for sudo fs operations
46 0           Rex::get_current_connection_object()->push_sudo_options( {} );
47              
48 0           $self->{mode} = $mode;
49 0           $self->{file} = $file;
50 0           $self->{rndfile} = get_tmp_file;
51 0 0         if ( $self->_fs->is_file($file) ) {
52              
53             # resolving symlinks
54 0           while ( my $link = $self->_fs->readlink($file) ) {
55 0 0         if ( $link !~ m/^\// ) {
56 0           $file = dirname($file) . "/" . $link;
57             }
58             else {
59 0           $file = $link;
60             }
61 0           $link = $self->_fs->readlink($link);
62             }
63 0           $self->{file_stat} = { $self->_fs->stat( $self->{file} ) };
64              
65 0           $self->_fs->cp( $file, $self->{rndfile} );
66 0           $self->_fs->chmod( 600, $self->{rndfile} );
67             $self->_fs->chown( Rex::Commands::connection->get_auth_user,
68 0           $self->{rndfile} );
69             }
70              
71 0           $self->{fh}->open( $mode, $self->{rndfile} );
72              
73 0           Rex::get_current_connection_object()->pop_sudo_options();
74              
75 0           return $self->{fh};
76             }
77              
78             sub read {
79 0     0 0   my ( $self, $len ) = @_;
80              
81 0           return $self->{fh}->read($len);
82             }
83              
84             sub write {
85 0     0 0   my ( $self, $buf ) = @_;
86              
87 0 0 0       utf8::encode($buf)
88             if Rex::Config->get_write_utf8_files && utf8::is_utf8($buf);
89              
90 0           $self->{fh}->write($buf);
91             }
92              
93             sub seek {
94 0     0 0   my ( $self, $pos ) = @_;
95 0           $self->{fh}->seek($pos);
96             }
97              
98             sub close {
99 0     0 0   my ($self) = @_;
100              
101 0 0         return unless $self->{fh};
102              
103             # always use current logged in user for sudo fs operations
104 0           Rex::get_current_connection_object()->push_sudo_options( {} );
105              
106 0           $self->{fh}->close;
107              
108 0 0 0       if ( exists $self->{mode}
      0        
109             && ( $self->{mode} eq ">" || $self->{mode} eq ">>" ) )
110             {
111              
112 0           my $exec = Rex::Interface::Exec->create;
113 0 0         if ( $self->{file_stat} ) {
114 0           my %stat = $self->_fs->stat( $self->{file} );
115 0           $self->_fs->chmod( $stat{mode}, $self->{rndfile} );
116 0           $self->_fs->chown( $stat{uid}, $self->{rndfile} );
117 0           $self->_fs->chgrp( $stat{gid}, $self->{rndfile} );
118             }
119 0           $self->_fs->rename( $self->{rndfile}, $self->{file} );
120              
121             #$exec->exec("cat " . $self->{rndfile} . " >'" . $self->{file} . "'");
122             }
123              
124 0           $self->{fh} = undef;
125              
126 0           $self->_fs->unlink( $self->{rndfile} );
127              
128 0           Rex::get_current_connection_object()->pop_sudo_options();
129              
130 0           $self = undef;
131             }
132              
133             sub _fs {
134 0     0     my ($self) = @_;
135 0           return Rex::Interface::Fs->create("Sudo");
136             }
137              
138             1;