Hide Show 53 lines of Pod
our
$VERSION
=
'1.16.0'
;
@EXPORT
=
qw(file_write file_read file_append
cat sed
delete_lines_matching append_if_no_such_line delete_lines_according_to
file template append_or_amend_line
extract)
;
use
vars
qw(%file_handles)
;
Hide Show 98 lines of Pod
sub
template {
my
(
$file
,
@params
) =
@_
;
my
$param
;
if
(
ref
$params
[0] eq
"HASH"
) {
$param
=
$params
[0];
}
else
{
$param
= {
@params
};
}
if
( !
exists
$param
->{server} ) {
$param
->{server} = Rex::Commands::connection()->server;
}
my
$content
;
if
(
ref
$file
&&
ref
$file
eq
'SCALAR'
) {
$content
= ${
$file
};
}
else
{
$file
= resolv_path(
$file
);
unless
(
$file
=~ m/^\// ||
$file
=~ m/^\@/ ) {
Rex::Logger::debug(
"Relativ path $file"
);
$file
= Rex::Helper::Path::get_file_path(
$file
,
caller
() );
Rex::Logger::debug(
"New filename: $file"
);
}
if
( -f
"$file."
. Rex::Config->get_environment ) {
$file
=
"$file."
. Rex::Config->get_environment;
}
if
( -f
$file
) {
$content
=
eval
{
local
(
@ARGV
, $/ ) = (
$file
); <>; };
}
elsif
(
$file
=~ m/^\@/ ) {
my
@caller
=
caller
(0);
my
$file_path
= Rex::get_module_path(
$caller
[0] );
if
( !-f
$file_path
) {
my
(
$mod_name
) = (
$caller
[0] =~ m/^.*::(.*?)$/ );
if
(
$mod_name
&& -f
"$file_path/$mod_name.pm"
) {
$file_path
=
"$file_path/$mod_name.pm"
;
}
elsif
( -f
"$file_path/__module__.pm"
) {
$file_path
=
"$file_path/__module__.pm"
;
}
elsif
( -f
"$file_path/Module.pm"
) {
$file_path
=
"$file_path/Module.pm"
;
}
elsif
( -f
$caller
[1] ) {
$file_path
=
$caller
[1];
}
elsif
(
$caller
[1] =~ m|^/loader/[^/]+/__Rexfile__.pm$| ) {
$file_path
=
$INC
{
"__Rexfile__.pm"
};
}
}
my
$file_content
=
eval
{
local
(
@ARGV
, $/ ) = (
$file_path
); <>; };
my
(
$data
) = (
$file_content
=~ m/.
*__DATA__
(.*)/ms );
my
$fp
= Rex::File::Parser::Data->new(
data
=> [
split
( /\n/,
$data
) ] );
my
$snippet_to_read
=
substr
(
$file
, 1 );
$content
=
$fp
->
read
(
$snippet_to_read
);
}
else
{
die
(
"$file not found"
);
}
}
my
%template_vars
;
if
( !
exists
$param
->{__no_sys_info__} ) {
%template_vars
= _get_std_template_vars(
$param
);
}
else
{
delete
$param
->{__no_sys_info__};
%template_vars
= %{
$param
};
}
my
$config_values
= Rex::Config->get_all;
for
my
$key
(
keys
%{
$config_values
} ) {
if
( !
exists
$template_vars
{
$key
} ) {
$template_vars
{
$key
} =
$config_values
->{
$key
};
}
}
if
( Rex::CMDB::cmdb_active() && Rex::Config->get_register_cmdb_template ) {
my
$data
= Rex::CMDB::cmdb();
for
my
$key
(
keys
%{
$data
->{value} } ) {
if
( !
exists
$template_vars
{
$key
} ) {
$template_vars
{
$key
} =
$data
->{value}->{
$key
};
}
}
}
return
Rex::Config->get_template_function()->(
$content
, \
%template_vars
);
}
sub
_get_std_template_vars {
my
(
$param
) =
@_
;
my
%merge1
= %{
$param
|| {} };
my
%merge2
;
if
( Rex::get_cache()->valid(
"system_information_info"
) ) {
%merge2
= %{ Rex::get_cache()->get(
"system_information_info"
) };
}
else
{
%merge2
= Rex::Helper::System::info();
Rex::get_cache()->set(
"system_information_info"
, \
%merge2
);
}
my
%template_vars
= (
%merge1
,
%merge2
);
return
%template_vars
;
}
Hide Show 109 lines of Pod
sub
file {
my
(
$file
,
@options
) =
@_
;
if
(
ref
$file
eq
"ARRAY"
) {
my
@ret
;
for
my
$f
( @{
$file
} ) {
push
(
@ret
, file(
$f
,
@options
) );
}
return
\
@ret
;
}
my
$option
= {
@options
};
$file
= resolv_path(
$file
);
my
(
$is_directory
);
if
(
exists
$option
->{ensure} &&
$option
->{ensure} eq
"directory"
) {
$is_directory
= 1;
}
if
(
exists
$option
->{source} && !
$is_directory
) {
$option
->{source} = resolv_path(
$option
->{source} );
}
$option
->{ensure} ||=
"present"
;
my
$fs
= Rex::Interface::Fs->create;
if
(
$option
->{ensure} ne
'absent'
&&
$fs
->is_symlink(
$file
) ) {
my
$original_file
=
$file
;
$file
= resolve_symlink(
$file
);
Rex::Logger::info(
"$original_file is a symlink, operating on $file instead"
,
'warn'
);
}
eval
{
my
@new_args
= Rex::Hook::run_hook(
file
=>
"before"
,
$file
, %{
$option
} );
if
(
@new_args
) {
(
$file
,
@options
) =
@new_args
;
$option
= {
@options
};
}
1;
} or
do
{
die
(
"Before hook failed. Cancelling file() action: $@"
);
};
Rex::get_current_connection()->{reporter}
->report_resource_start(
type
=>
"file"
,
name
=>
$file
);
my
$need_md5
= (
$option
->{
"on_change"
} && !
$is_directory
? 1 : 0 );
my
$on_change
=
$option
->{
"on_change"
} ||
sub
{ };
my
$on_no_change
=
$option
->{
"on_no_change"
} ||
sub
{ };
my
$__ret
= {
changed
=> 0 };
my
(
$new_md5
,
$old_md5
);
if
(
exists
$option
->{no_overwrite}
&&
$option
->{no_overwrite}
&&
$fs
->is_file(
$file
) )
{
Rex::Logger::debug(
"File already exists and no_overwrite option given. Doing nothing."
);
$__ret
= {
changed
=> 0 };
Rex::get_current_connection()->{reporter}->report(
changed
=> 0,
message
=>
"File already exists and no_overwrite option given. Doing nothing."
);
}
elsif
( (
exists
$option
->{content} ||
exists
$option
->{source} )
&& !
$is_directory
)
{
my
$tmp_file_name
= get_tmp_file_name(
$file
);
if
(
exists
$option
->{content} ) {
my
$fh
= file_write(
$tmp_file_name
);
my
@lines
=
split
(
qr{$/}
,
$option
->{
"content"
} );
for
my
$line
(
@lines
) {
$fh
->
write
(
$line
. $/ );
}
$fh
->
close
;
}
elsif
(
exists
$option
->{source} ) {
$option
->{source} =
Rex::Helper::Path::get_file_path(
$option
->{source},
caller
);
upload
$option
->{source},
$tmp_file_name
;
}
eval
{
$old_md5
= md5(
$file
); };
$new_md5
= md5(
$tmp_file_name
);
if
(
$new_md5
&&
$old_md5
&&
$new_md5
eq
$old_md5
) {
Rex::Logger::debug(
"No need to overwrite existing file. Old and new files are the same. $old_md5 eq $new_md5."
);
$fs
->
unlink
(
$tmp_file_name
);
$need_md5
= 0;
Rex::get_current_connection()->{reporter}->report(
changed
=> 0,
message
=>
"No need to overwrite existing file. Old and new files are the same. $old_md5 eq $new_md5."
);
}
else
{
$old_md5
||=
""
;
Rex::Logger::debug(
"Need to use the new file. md5 sums are different. <<$old_md5>> = <<$new_md5>>"
);
Rex::Hook::run_hook(
file
=>
"before_change"
,
$file
, %{
$option
} );
if
(Rex::is_sudo) {
my
$current_options
=
Rex::get_current_connection_object()->get_current_sudo_options;
Rex::get_current_connection_object()->push_sudo_options( {} );
if
(
exists
$current_options
->{user} ) {
$fs
->
chown
(
"$current_options->{user}:"
,
$tmp_file_name
);
}
}
$fs
->
rename
(
$tmp_file_name
,
$file
);
Rex::get_current_connection_object()->pop_sudo_options()
if
(Rex::is_sudo);
$__ret
= {
changed
=> 1 };
Rex::get_current_connection()->{reporter}->report(
changed
=> 1,
message
=>
"File updated. old md5: $old_md5, new md5: $new_md5"
);
Rex::Hook::run_hook(
file
=>
"after_change"
,
$file
, %{
$option
},
$__ret
);
}
}
if
(
exists
$option
->{
"ensure"
} ) {
if
(
$option
->{ensure} eq
"present"
) {
if
( !
$fs
->is_file(
$file
) ) {
Rex::Hook::run_hook(
file
=>
"before_change"
,
$file
, %{
$option
} );
my
$fh
= file_write(
$file
);
$fh
->
write
(
""
);
$fh
->
close
;
$__ret
= {
changed
=> 1 };
Rex::get_current_connection()->{reporter}->report(
changed
=> 1,
message
=>
"file is now present, with no content"
,
);
Rex::Hook::run_hook(
file
=>
"after_change"
,
$file
, %{
$option
},
$__ret
);
}
elsif
( !
$__ret
->{changed} ) {
$__ret
= {
changed
=> 0 };
Rex::get_current_connection()->{reporter}->report(
changed
=> 0, );
}
}
elsif
(
$option
->{ensure} eq
"absent"
) {
$need_md5
= 0;
Rex::Hook::run_hook(
file
=>
"before_change"
,
$file
, %{
$option
} );
if
(
$fs
->is_file(
$file
) ) {
$fs
->
unlink
(
$file
);
$__ret
= {
changed
=> 1 };
Rex::get_current_connection()->{reporter}->report(
changed
=> 1,
message
=>
"File removed."
);
}
elsif
(
$fs
->is_dir(
$file
) ) {
$fs
->
rmdir
(
$file
);
$__ret
= {
changed
=> 1 };
Rex::get_current_connection()->{reporter}->report(
changed
=> 1,
message
=>
"Directory removed."
,
);
}
else
{
$__ret
= {
changed
=> 0 };
Rex::get_current_connection()->{reporter}->report(
changed
=> 0, );
}
Rex::Hook::run_hook(
file
=>
"after_change"
,
$file
, %{
$option
},
$__ret
);
}
elsif
(
$option
->{ensure} eq
"directory"
) {
Rex::Logger::debug(
"file() should be a directory"
);
my
%dir_option
;
if
(
exists
$option
->{owner} ) {
$dir_option
{owner} =
$option
->{owner};
}
if
(
exists
$option
->{group} ) {
$dir_option
{group} =
$option
->{group};
}
if
(
exists
$option
->{mode} ) {
$dir_option
{mode} =
$option
->{mode};
}
Rex::Commands::Fs::
mkdir
(
$file
,
%dir_option
,
on_change
=>
$on_change
);
}
}
if
( !
exists
$option
->{content}
&& !
exists
$option
->{source}
&&
$option
->{ensure} ne
"absent"
)
{
if
( !
$fs
->is_file(
$file
) && !
$is_directory
) {
Rex::Hook::run_hook(
file
=>
"before_change"
,
$file
, %{
$option
} );
my
$fh
= file_write(
$file
);
$fh
->
write
(
""
);
$fh
->
close
;
my
$f_type
=
"file is now present, with no content"
;
if
(
exists
$option
->{ensure} &&
$option
->{ensure} eq
"directory"
) {
$f_type
=
"directory is now present"
;
}
Rex::get_current_connection()->{reporter}->report(
changed
=> 1,
message
=>
$f_type
,
);
Rex::Hook::run_hook(
file
=>
"after_change"
,
$file
, %{
$option
},
$__ret
);
}
}
if
(
$option
->{ensure} ne
"absent"
) {
if
(
$need_md5
) {
eval
{
$new_md5
= md5(
$file
); };
}
my
%stat_old
=
$fs
->
stat
(
$file
);
if
(
exists
$option
->{
"mode"
} ) {
$fs
->
chmod
(
$option
->{
"mode"
},
$file
);
}
if
(
exists
$option
->{
"group"
} ) {
$fs
->chgrp(
$option
->{
"group"
},
$file
);
}
if
(
exists
$option
->{
"owner"
} ) {
$fs
->
chown
(
$option
->{
"owner"
},
$file
);
}
my
%stat_new
=
$fs
->
stat
(
$file
);
if
(
%stat_old
&&
%stat_new
&&
$stat_old
{mode} ne
$stat_new
{mode} ) {
Rex::get_current_connection()->{reporter}->report(
changed
=> 1,
message
=>
"File-System permissions changed from $stat_old{mode} to $stat_new{mode}."
,
);
}
if
(
%stat_old
&&
%stat_new
&&
$stat_old
{uid} ne
$stat_new
{uid} ) {
Rex::get_current_connection()->{reporter}->report(
changed
=> 1,
message
=>
"Owner changed from $stat_old{uid} to $stat_new{uid}."
,
);
}
if
(
%stat_old
&&
%stat_new
&&
$stat_old
{gid} ne
$stat_new
{gid} ) {
Rex::get_current_connection()->{reporter}->report(
changed
=> 1,
message
=>
"Group changed from $stat_old{gid} to $stat_new{gid}."
,
);
}
}
my
$on_change_done
= 0;
if
(
$need_md5
) {
unless
(
$old_md5
&&
$new_md5
&&
$old_md5
eq
$new_md5
) {
$old_md5
||=
""
;
$new_md5
||=
""
;
Rex::Logger::debug(
"File $file has been changed... Running on_change"
);
Rex::Logger::debug(
"old: $old_md5"
);
Rex::Logger::debug(
"new: $new_md5"
);
&$on_change
(
$file
);
$on_change_done
= 1;
Rex::get_current_connection()->{reporter}->report(
changed
=> 1,
message
=>
"Content changed."
,
);
$__ret
= {
changed
=> 1 };
}
}
if
(
$__ret
->{changed} == 1 &&
$on_change_done
== 0 ) {
&$on_change
(
$file
);
}
elsif
(
$__ret
->{changed} == 0 ) {
Rex::Logger::debug(
"File $file has not been changed... Running on_no_change"
);
&$on_no_change
(
$file
);
}
Rex::Hook::run_hook(
file
=>
"after"
,
$file
, %{
$option
},
$__ret
);
Rex::get_current_connection()->{reporter}
->report_resource_end(
type
=>
"file"
,
name
=>
$file
);
return
$__ret
->{changed};
}
sub
get_tmp_file_name {
my
$file
=
shift
;
my
$dirname
= dirname(
$file
);
my
$filename
=
".rex.tmp."
. basename(
$file
);
my
$tmp_file_name
=
$dirname
eq
'.'
?
$filename
: Rex::Helper::File::Spec->catfile(
$dirname
,
$filename
);
return
$tmp_file_name
;
}
Hide Show 22 lines of Pod
sub
file_write {
my
(
$file
) =
@_
;
$file
= resolv_path(
$file
);
Rex::Logger::debug(
"Opening file: $file for writing."
);
my
$fh
= Rex::Interface::File->create;
if
( !
$fh
->
open
(
">"
,
$file
) ) {
Rex::Logger::debug(
"Can't open $file for writing."
);
die
(
"Can't open $file for writing."
);
}
return
Rex::FS::File->new(
fh
=>
$fh
);
}
Hide Show 4 lines of Pod
sub
file_append {
my
(
$file
) =
@_
;
$file
= resolv_path(
$file
);
Rex::Logger::debug(
"Opening file: $file for appending."
);
my
$fh
= Rex::Interface::File->create;
if
( !
$fh
->
open
(
">>"
,
$file
) ) {
Rex::Logger::debug(
"Can't open $file for appending."
);
die
(
"Can't open $file for appending."
);
}
return
Rex::FS::File->new(
fh
=>
$fh
);
}
Hide Show 22 lines of Pod
sub
file_read {
my
(
$file
) =
@_
;
$file
= resolv_path(
$file
);
Rex::Logger::debug(
"Opening file: $file for reading."
);
my
$fh
= Rex::Interface::File->create;
if
( !
$fh
->
open
(
"<"
,
$file
) ) {
Rex::Logger::debug(
"Can't open $file for reading."
);
die
(
"Can't open $file for reading."
);
}
return
Rex::FS::File->new(
fh
=>
$fh
);
}
Hide Show 8 lines of Pod
sub
cat {
my
(
$file
) =
@_
;
$file
= resolv_path(
$file
);
my
$fh
= file_read(
$file
);
unless
(
$fh
) {
die
(
"Can't open $file for reading"
);
}
my
$content
=
$fh
->read_all;
$fh
->
close
;
return
$content
;
}
Hide Show 10 lines of Pod
sub
delete_lines_matching {
my
(
$file
,
@m
) =
@_
;
$file
= resolv_path(
$file
);
Rex::get_current_connection()->{reporter}
->report_resource_start(
type
=>
"delete_lines_matching"
,
name
=>
$file
);
for
(
@m
) {
if
(
ref
(
$_
) ne
"Regexp"
) {
$_
=
qr{\Q$_\E}
;
}
}
my
$fs
= Rex::Interface::Fs->create;
my
%stat
=
$fs
->
stat
(
$file
);
if
( !
$fs
->is_file(
$file
) ) {
Rex::Logger::info(
"File: $file not found."
);
die
(
"$file not found"
);
}
if
( !
$fs
->is_writable(
$file
) ) {
Rex::Logger::info(
"File: $file not writable."
);
die
(
"$file not writable"
);
}
my
$nl
= $/;
my
@content
=
split
( /
$nl
/, cat(
$file
) );
my
$old_md5
=
""
;
eval
{
$old_md5
= md5(
$file
); };
my
@new_content
;
OUT:
for
my
$line
(
@content
) {
IN:
for
my
$match
(
@m
) {
if
(
$line
=~
$match
) {
next
OUT;
}
}
push
@new_content
,
$line
;
}
file
$file
,
content
=>
join
(
$nl
,
@new_content
),
owner
=>
$stat
{uid},
group
=>
$stat
{gid},
mode
=>
$stat
{mode};
my
$new_md5
=
""
;
eval
{
$new_md5
= md5(
$file
); };
if
(
$new_md5
ne
$old_md5
) {
Rex::get_current_connection()->{reporter}->report(
changed
=> 1,
message
=>
"Content changed."
,
);
}
else
{
Rex::get_current_connection()->{reporter}->report(
changed
=> 0, );
}
Rex::get_current_connection()->{reporter}
->report_resource_end(
type
=>
"delete_lines_matching"
,
name
=>
$file
);
}
Hide Show 15 lines of Pod
sub
delete_lines_according_to {
my
(
$search
,
$file
,
@options
) =
@_
;
$file
= resolv_path(
$file
);
my
$option
= {
@options
};
my
$on_change
=
$option
->{on_change} ||
undef
;
my
$on_no_change
=
$option
->{on_no_change} ||
undef
;
my
(
$old_md5
,
$new_md5
);
if
(
$on_change
) {
$old_md5
= md5(
$file
);
}
delete_lines_matching(
$file
,
$search
);
if
(
$on_change
||
$on_no_change
) {
$new_md5
= md5(
$file
);
if
(
$old_md5
ne
$new_md5
) {
&$on_change
(
$file
)
if
$on_change
;
}
else
{
&$on_no_change
(
$file
)
if
$on_no_change
;
}
}
}
Hide Show 27 lines of Pod
sub
append_if_no_such_line {
_append_or_update(
'append_if_no_such_line'
,
@_
);
}
Hide Show 19 lines of Pod
sub
append_or_amend_line {
_append_or_update(
'append_or_amend_line'
,
@_
);
}
sub
_append_or_update {
my
$action
=
shift
;
my
$file
=
shift
;
$file
= resolv_path(
$file
);
my
(
$new_line
,
@m
);
my
(
$option
,
$on_change
,
$on_no_change
);
Rex::get_current_connection()->{reporter}
->report_resource_start(
type
=>
$action
,
name
=>
$file
);
eval
{
no
warnings;
$option
= {
@_
};
if
( !
exists
$option
->{line} ) {
die
;
}
$new_line
=
$option
->{line};
if
(
exists
$option
->{regexp} &&
ref
$option
->{regexp} eq
"Regexp"
) {
@m
= (
$option
->{regexp} );
}
elsif
(
ref
$option
->{regexp} eq
"ARRAY"
) {
@m
= @{
$option
->{regexp} };
}
$on_change
=
$option
->{on_change} ||
undef
;
$on_no_change
=
$option
->{on_no_change} ||
undef
;
1;
} or
do
{
(
$new_line
,
@m
) =
@_
;
for
my
$option
( [
on_change
=> \
$on_change
],
[
on_no_change
=> \
$on_no_change
] )
{
for
(
my
$i
= 0 ;
$i
<
$#m
;
$i
++ ) {
if
(
$m
[
$i
] eq
$option
->[0] &&
ref
(
$m
[
$i
+ 1 ] ) eq
"CODE"
) {
${
$option
->[1] } =
$m
[
$i
+ 1 ];
splice
(
@m
,
$i
, 2 );
last
;
}
}
}
};
unless
(
defined
$new_line
) {
my
(
undef
,
undef
,
undef
,
$subroutine
) =
caller
(1);
$subroutine
=~ s/^.*:://;
die
"Undefined new line while trying to run $subroutine on $file"
;
}
my
$fs
= Rex::Interface::Fs->create;
my
%stat
=
$fs
->
stat
(
$file
);
my
(
$old_md5
,
$ret
);
$old_md5
= md5(
$file
);
my
$content
;
eval
{
$content
= [
split
( /\n/, cat(
$file
) ) ];
1;
} or
do
{
$ret
= 1;
};
if
( !
@m
) {
push
@m
,
qr{\Q$new_line\E}
;
}
my
$found
;
for
my
$line
( 0 .. $
for
my
$match
(
@m
) {
if
(
ref
(
$match
) ne
"Regexp"
) {
$match
=
qr{$match}
;
}
if
(
$content
->[
$line
] =~
$match
) {
$found
= 1;
last
if
$action
eq
'append_if_no_such_line'
;
$content
->[
$line
] =
"$new_line"
;
}
}
}
my
$new_md5
;
if
(
$action
eq
'append_if_no_such_line'
&&
$found
) {
$new_md5
=
$old_md5
;
}
else
{
push
@$content
,
"$new_line"
unless
$found
;
file
$file
,
content
=>
join
(
"\n"
,
@$content
),
owner
=>
$stat
{uid},
group
=>
$stat
{gid},
mode
=>
$stat
{mode};
$new_md5
= md5(
$file
);
}
if
(
$on_change
||
$on_no_change
) {
if
(
$old_md5
&&
$new_md5
&&
$old_md5
ne
$new_md5
) {
if
(
$on_change
) {
$old_md5
||=
""
;
$new_md5
||=
""
;
Rex::Logger::debug(
"File $file has been changed... Running on_change"
);
Rex::Logger::debug(
"old: $old_md5"
);
Rex::Logger::debug(
"new: $new_md5"
);
&$on_change
(
$file
);
}
}
elsif
(
$on_no_change
) {
$new_md5
||=
""
;
Rex::Logger::debug(
"File $file has not been changed (md5 $new_md5)... Running on_no_change"
);
&$on_no_change
(
$file
);
}
}
if
(
$old_md5
&&
$new_md5
&&
$old_md5
ne
$new_md5
) {
Rex::get_current_connection()->{reporter}->report(
changed
=> 1,
message
=>
"Content changed."
,
);
}
else
{
Rex::get_current_connection()->{reporter}->report(
changed
=> 0, );
}
Rex::get_current_connection()->{reporter}
->report_resource_end(
type
=>
$action
,
name
=>
$file
);
}
Hide Show 21 lines of Pod
sub
extract {
my
(
$file
,
%option
) =
@_
;
$file
= resolv_path(
$file
);
my
$pre_cmd
=
""
;
my
$to
=
"."
;
my
$type
=
""
;
if
(
$option
{
chdir
} ) {
$to
=
$option
{
chdir
};
}
if
(
$option
{to} ) {
$to
=
$option
{to};
}
$to
= resolv_path(
$to
);
if
(
$option
{type} ) {
$type
=
$option
{type};
}
Rex::Commands::Fs::
mkdir
(
$to
);
$pre_cmd
=
"cd $to; "
;
my
$exec
= Rex::Interface::Exec->create;
my
$cmd
=
""
;
if
(
$type
eq
'tgz'
||
$file
=~ m/\.tar\.gz$/
||
$file
=~ m/\.tgz$/
||
$file
=~ m/\.tar\.Z$/ )
{
$cmd
=
"${pre_cmd}gunzip -c $file | tar -xf -"
;
}
elsif
(
$type
eq
'tbz'
||
$file
=~ m/\.tar\.bz2/ ||
$file
=~ m/\.tbz2/ ) {
$cmd
=
"${pre_cmd}bunzip2 -c $file | tar -xf -"
;
}
elsif
(
$type
eq
'tar'
||
$file
=~ m/\.(tar|box)/ ) {
$cmd
=
"${pre_cmd}tar -xf $file"
;
}
elsif
(
$type
eq
'zip'
||
$file
=~ m/\.(zip|war|jar)$/ ) {
$cmd
=
"${pre_cmd}unzip -o $file"
;
}
elsif
(
$type
eq
'gz'
||
$file
=~ m/\.gz$/ ) {
$cmd
=
"${pre_cmd}gunzip -f $file"
;
}
elsif
(
$type
eq
'bz2'
||
$file
=~ m/\.bz2$/ ) {
$cmd
=
"${pre_cmd}bunzip2 -f $file"
;
}
else
{
Rex::Logger::info(
"File not supported."
);
die
(
"File ($file) not supported."
);
}
$exec
->
exec
(
$cmd
);
my
$fs
= Rex::Interface::Fs->create;
if
(
$option
{owner} ) {
$fs
->
chown
(
$option
{owner},
$to
,
recursive
=> 1 );
}
if
(
$option
{group} ) {
$fs
->chgrp(
$option
{group},
$to
,
recursive
=> 1 );
}
if
(
$option
{mode} ) {
$fs
->
chmod
(
$option
{mode},
$to
,
recursive
=> 1 );
}
}
Hide Show 17 lines of Pod
sub
sed {
my
(
$search
,
$replace
,
$file
,
@option
) =
@_
;
$file
= resolv_path(
$file
);
my
$options
= {};
Rex::get_current_connection()->{reporter}
->report_resource_start(
type
=>
"sed"
,
name
=>
$file
);
if
(
ref
(
$option
[0] ) ) {
$options
=
$option
[0];
}
else
{
$options
= {
@option
};
}
my
$on_change
=
$options
->{
"on_change"
} ||
undef
;
my
$on_no_change
=
$options
->{
"on_no_change"
} ||
undef
;
my
@content
;
if
(
exists
$options
->{multiline} ) {
$content
[0] = cat(
$file
);
$content
[0] =~ s/
$search
/
$replace
/gms;
}
else
{
@content
=
split
( /\n/, cat(
$file
) );
for
(
@content
) {
s/
$search
/
$replace
/;
}
}
my
$fs
= Rex::Interface::Fs->create;
my
%stat
=
$fs
->
stat
(
$file
);
my
$ret
= file(
$file
,
content
=>
join
(
"\n"
,
@content
),
on_change
=>
$on_change
,
on_no_change
=>
$on_no_change
,
owner
=>
$stat
{uid},
group
=>
$stat
{gid},
mode
=>
$stat
{mode}
);
Rex::get_current_connection()->{reporter}
->report_resource_end(
type
=>
"sed"
,
name
=>
$file
);
return
$ret
;
}
1;