our
$VERSION
=
'1.16.0'
;
sub
new {
my
$that
=
shift
;
my
$proto
=
ref
(
$that
) ||
$that
;
my
$self
= {
@_
};
bless
(
$self
,
$proto
);
return
$self
;
}
sub
list {
my
(
$self
) =
@_
;
return
@{
$self
->{cron} };
}
sub
list_jobs {
my
(
$self
) =
@_
;
my
@jobs
= @{
$self
->{cron} };
my
@ret
=
map
{ {
line
=>
$_
->{line}, %{
$_
->{cron} } } }
grep
{
$_
->{type} eq
"job"
}
@jobs
;
}
sub
list_envs {
my
(
$self
) =
@_
;
my
@jobs
= @{
$self
->{cron} };
my
@ret
=
grep
{
$_
->{type} eq
"env"
}
@jobs
;
}
sub
add {
my
(
$self
,
%config
) =
@_
;
%config
=
$self
->_create_defaults(
%config
);
my
$new_cron
=
sprintf
(
"%s %s %s %s %s %s"
,
$config
{
"minute"
},
$config
{
"hour"
},
$config
{
"day_of_month"
},
$config
{
"month"
},
$config
{
"day_of_week"
},
$config
{
"command"
},
);
my
$dupe
=
grep
{
$_
->{line} eq
$new_cron
} @{
$self
->{cron} };
if
(
$dupe
) {
Rex::Logger::debug(
"Job \"$new_cron\" already installed, skipping."
);
return
0;
}
push
(
@{
$self
->{cron} },
{
type
=>
"job"
,
line
=>
$new_cron
,
cron
=> \
%config
,
}
);
return
1;
}
sub
add_env {
my
(
$self
,
$name
,
$value
) =
@_
;
my
$env_index
= 0;
my
$exists
= 0;
for
my
$env
(
$self
->list_envs ) {
if
(
$env
->{name} eq
"$name"
) {
if
(
$env
->{value} ne
"\"$value\""
) {
Rex::Logger::debug(
"Environment variable changed : $name"
);
$self
->delete_env(
$env_index
);
}
else
{
Rex::Logger::debug(
"Environment variable already exists with same value: $name=$value"
);
$exists
= 1;
}
}
$env_index
++;
}
if
(
$exists
== 0 ) {
unshift
(
@{
$self
->{cron} },
{
type
=>
"env"
,
line
=>
"$name=\"$value\""
,
name
=>
$name
,
value
=>
$value
,
}
);
}
}
sub
delete_job {
my
(
$self
,
$num
) =
@_
;
my
@jobs
=
$self
->list_jobs;
my
$i
= 0;
my
$to_delete
;
for
my
$j
( @{
$self
->{cron} } ) {
if
(
$j
->{line} eq
$jobs
[
$num
]->{line} ) {
$to_delete
=
$i
;
last
;
}
$i
++;
}
unless
(
defined
$to_delete
) {
die
(
"Cron Entry $num not found."
);
}
$self
->
delete
(
$to_delete
);
}
sub
delete_env {
my
(
$self
,
$num
) =
@_
;
my
@jobs
=
$self
->list_envs;
my
$i
= 0;
my
$to_delete
;
for
my
$j
( @{
$self
->{cron} } ) {
if
(
$j
->{line} eq
$jobs
[
$num
]->{line} ) {
$to_delete
=
$i
;
last
;
}
$i
++;
}
unless
(
defined
$to_delete
) {
die
(
"Cron Entry $num not found."
);
}
$self
->
delete
(
$to_delete
);
}
sub
delete
{
my
(
$self
,
$num
) =
@_
;
splice
( @{
$self
->{cron} },
$num
, 1 );
}
sub
write_cron {
my
(
$self
) =
@_
;
my
$rnd_file
= get_tmp_file;
my
@lines
=
map
{
$_
->{line} } @{
$self
->{cron} };
my
$fh
= file_write
$rnd_file
;
$fh
->
write
(
join
(
"\n"
,
@lines
) .
"\n"
);
$fh
->
close
;
return
$rnd_file
;
}
sub
activate_user_cron {
my
(
$self
,
$file
,
$user
) =
@_
;
$user
=
undef
if
$user
eq
&_whoami
;
my
$command
=
'crontab'
;
$command
.=
" -u $user"
if
defined
$user
;
i_run
"$command $file"
;
unlink
$file
;
}
sub
read_user_cron {
my
(
$self
,
$user
) =
@_
;
$user
=
undef
if
$user
eq
&_whoami
;
my
$command
=
'crontab -l'
;
$command
.=
" -u $user"
if
defined
$user
;
$command
.=
' 2> /dev/null'
;
my
@lines
= i_run
$command
,
fail_ok
=> 1;
$self
->parse_cron(
@lines
);
}
sub
parse_cron {
my
(
$self
,
@lines
) =
@_
;
chomp
@lines
;
my
@cron
;
for
my
$line
(
@lines
) {
if
(
$line
=~ m/^
push
(
@cron
,
{
type
=>
"comment"
,
line
=>
$line
,
}
);
}
elsif
(
$line
=~ m/^\s*$/ ) {
push
(
@cron
,
{
type
=>
"empty"
,
line
=>
$line
,
}
);
}
elsif
(
$line
=~ m/^(@|\*|[0-9])/ ) {
my
(
$min
,
$hour
,
$day
,
$month
,
$dow
,
$cmd
) =
split
( /\s+/,
$line
, 6 );
push
(
@cron
,
{
type
=>
"job"
,
line
=>
$line
,
cron
=> {
minute
=>
$min
,
hour
=>
$hour
,
day_of_month
=>
$day
,
month
=>
$month
,
day_of_week
=>
$dow
,
command
=>
$cmd
,
},
}
);
}
elsif
(
$line
=~ m/=/ ) {
my
(
$name
,
$value
) =
split
( /=/,
$line
, 2 );
$name
=~ s/^\s+//;
$name
=~ s/\s+$//;
$value
=~ s/^\s+//;
$value
=~ s/\s+$//;
push
(
@cron
,
{
type
=>
"env"
,
line
=>
$line
,
name
=>
$name
,
value
=>
$value
,
}
);
}
else
{
Rex::Logger::debug(
"Error parsing cron line: $line"
);
next
;
}
}
$self
->{cron} = \
@cron
;
return
@cron
;
}
sub
_create_defaults {
my
(
$self
,
%config
) =
@_
;
$config
{
"minute"
} =
"*"
unless
defined
$config
{minute};
$config
{
"hour"
} =
"*"
unless
defined
$config
{hour};
$config
{
"day_of_month"
} =
"*"
unless
defined
$config
{day_of_month};
$config
{
"month"
} =
"*"
unless
defined
$config
{month};
$config
{
"day_of_week"
} =
"*"
unless
defined
$config
{day_of_week};
$config
{
"command"
} ||=
"false"
;
return
%config
;
}
sub
_whoami {
return
i_run
q(perl -e 'print scalar getpwuid($<)
');
}
1;