=head1 webmincron-lib.pl Functions for creating and listing Webmin scheduled functions. =cut BEGIN { push(@INC, ".."); }; use WebminCore; use feature 'state'; &init_config(); $webmin_crons_directory = "$module_config_directory/crons"; @special_modes = ( 'hourly', 'daily', 'weekly', 'monthly', 'yearly' ); =head2 list_webmin_crons Returns a list of all scheduled Webmin functions. Each of which is a hash ref with keys : =item id - A unique ID number =item module - The module in which the function is defined =item file - File in which the function is declared =item func - Name of the function to call =item args - Array ref of strings to pass to the function as parameters =item interval - Number of seconds between runs (optional) =item mins - Minutes on which to run. Can be * or a comma-separated list =item hours - Hours on which to run =item days - Days of the month on which to run =item months - Months of the year on which to run =item weekdays - Days of week on which to run =item special - Can be 'hourly', 'daily', 'weekly' or 'monthly' =cut sub list_webmin_crons { my @rv; opendir(CRONS, $webmin_crons_directory) || return ( ); foreach my $f (readdir(CRONS)) { if ($f =~ /^(\d+)\.cron$/) { my %cron; &read_file_cached("$webmin_crons_directory/$f", \%cron); $cron{'id'} = $1; my @args; for(my $i=0; defined($cron{'arg'.$i}); $i++) { push(@args, $cron{'arg'.$i}); delete($cron{'arg'.$i}); } if (@args) { $cron{'args'} = \@args; } push(@rv, \%cron); } } return @rv; } =head2 save_webmin_crons(&cron) Create or update a webmin cron function. Also locks the file being written to. =cut sub save_webmin_cron { my ($cron) = @_; state $cnt = 0; if (!-d $webmin_crons_directory) { &make_dir($webmin_crons_directory, 0700); } if (!$cron->{'id'}) { $cron->{'id'} = time().$$.($cnt++); } my $file = "$webmin_crons_directory/$cron->{'id'}.cron"; my %wcron = %$cron; if ($wcron{'args'}) { for(my $i=0; $i<@{$wcron{'args'}}; $i++) { $wcron{'arg'.$i} = $wcron{'args'}->[$i]; } delete($wcron{'args'}); } &lock_file($file); &write_file($file, \%wcron); &unlock_file($file); &reload_miniserv(1); } =head2 delete_webmin_cron(&cron) Deletes the file for a webmin cron function. Also does locking. =cut sub delete_webmin_cron { my ($cron) = @_; my $file = "$webmin_crons_directory/$cron->{'id'}.cron"; &lock_file($file); &unlink_file($file); &unlock_file($file); &reload_miniserv(1); } =head2 find_webmin_cron(module, function, [&args]) Returns a Webmin cron hash ref matching the given module and function =cut sub find_webmin_cron { my ($module, $func, $args) = @_; my @crons = &list_webmin_crons(); foreach my $oc (@crons) { next if ($oc->{'module'} ne $module); next if ($oc->{'func'} ne $func); if ($args) { my $sameargs = 1; for(my $i=0; $i < scalar(@{$oc->{'args'}}) || $i < scalar(@$args); $i++) { $sameargs = 0 if ($oc->{'args'}->[$i] ne $args->[$i]); } next if (!$sameargs); } return $oc; } return undef; } =head2 create_webmin_cron(&cron, [old-cron-command]) Create or update a webmin cron job that calls some function. If the old-cron parameter is given, find and replace the regular cron job of that name. =cut sub create_webmin_cron { my ($cron, $old_cmd) = @_; # Find and replace existing cron with same module, function and args my $already = &find_webmin_cron($cron->{'module'}, $cron->{'func'}, $cron->{'args'}); if ($already) { # Update existing, possibly with new interval $cron->{'id'} = $already->{'id'}; } &save_webmin_cron($cron); # Find and delete any Unix cron job that this is replacing if ($old_cmd && &foreign_installed("cron")) { &foreign_require("cron"); my @jobs = &cron::list_cron_jobs(); @jobs = grep { $_->{'user'} eq 'root' && $_->{'command'} =~ /(^|[ \|\&;\/])\Q$old_cmd\E($|[ \|\&><;])/ } @jobs; foreach my $job (reverse(@jobs)) { &lock_file(&cron::cron_file($job)); &cron::delete_cron_job($job); &unlock_file(&cron::cron_file($job)); } } } =head2 delete_webmin_module_crons(module) Remove all Webmin cron jobs for some module =cut sub delete_webmin_module_crons { my ($mod) = @_; foreach my $cron (&list_webmin_crons()) { if ($cron->{'module'} eq $mod) { &delete_webmin_cron($cron); } } } =head2 show_times_input(&job, [special]) Returns HTML for inputs for selecting the schedule for a cron job, defined by the first parameter which must be a hash ref returned by list_cron_jobs. =item job - Hash ref for a webmincron object =item special - 0=don't allow special times (like @hourly), 1=allow =cut sub show_times_input { my ($job, $special) = @_; $special = 0 if (!defined($special)); my $rv = "
| \n"; $rv .= &ui_radio("special_def", $job->{'special'} ? 1 : 0, [ [ 1, $text{'edit_special1'}." ". &ui_select("special", $job->{'special'}, [ map { [ $_, $text{'edit_special_'.$_} ] } @special_modes ]) ], [ 0, $text{'edit_special0'} ] ]); $rv .= " | |||||
| $text{'edit_mins'} | ". "$text{'edit_hours'} | ". "$text{'edit_days'} | ". "$text{'edit_months'} | ". "$text{'edit_weekdays'} | "; $rv .= "|
| \n";
$rv .= sprintf
" %s \n", $arr eq "mins" && $hourly_only ? "disabled" : "", $job->{$arr} eq "*" || $job->{$arr} eq "" ? "checked" : "", "onClick='enable_cron_fields(\"$arr\", form, 0)'", $text{'edit_all'}; $rv .= sprintf " %s \n", $job->{$arr} eq "*" || $job->{$arr} eq "" ? "" : "checked", "onClick='enable_cron_fields(\"$arr\", form, 1)'", $text{'edit_selected'}; $rv .= "
| \n";
}
$rv .= "|||||