Handle hostnames with upper-case letters
[webmin.git] / cron / index.cgi
1 #!/usr/local/bin/perl
2 # index.cgi
3 # Display a list of all cron jobs, with the username and command for each one
4
5 require './cron-lib.pl';
6 &ReadParse();
7 &ui_print_header(undef, $text{'index_title'}, "", undef, 1, 1);
8 $max_jobs = $userconfig{'max_jobs'} || $config{'max_jobs'};
9
10 # Make sure cron is installed (very likely!)
11 $err = &check_cron_config();
12 if ($err) {
13         print $err,"<p>\n";
14         &ui_print_footer("/", $text{'index'});
15         exit;
16         }
17
18 # Work out which users can be viewed
19 map { $ucan{$_}++ } split(/\s+/, $access{'users'});
20 @jobs = &list_cron_jobs();
21 @ulist = &unique(map { $_->{'user'} } @jobs);
22 if ($access{'mode'} == 1) {
23         @ulist = grep { $ucan{$_} } @ulist;
24         }
25 elsif ($access{'mode'} == 2) {
26         @ulist = grep { !$ucan{$_} } @ulist;
27         }
28 elsif ($access{'mode'} == 3) {
29         @ulist = ( $remote_user );
30         }
31 elsif ($access{'mode'} == 4) {
32         @ulist = grep { local @u = getpwnam($_);
33                         (!$access{'uidmin'} || $u[2] >= $access{'uidmin'}) &&
34                         (!$access{'uidmax'} || $u[2] <= $access{'uidmax'}) }
35                       @ulist;
36         }
37 elsif ($access{'mode'} == 5) {
38         @ulist = grep { local @u = getpwnam($_);
39                         $u[3] == $access{'users'} } @ulist;
40         }
41
42 if ($config{'show_run'}) {
43         &foreign_require("proc", "proc-lib.pl");
44         @procs = &proc::list_processes();
45         }
46
47 # Work out creation links
48 @crlinks = ( );
49 if ($access{'create'}) {
50         push(@crlinks,
51              "<a href=\"edit_cron.cgi?new=1\">$text{'index_create'}</a>");
52         push(@crlinks,
53              "<a href=\"edit_env.cgi?new=1\">$text{'index_ecreate'}</a>")
54                 if ($env_support);
55         }
56 if ($config{cron_allow_file} && $config{cron_deny_file} && $access{'allow'}) {
57         push(@crlinks, "<a href=edit_allow.cgi>$text{'index_allow'}</a>");
58         }
59
60 # Build a list of cron job rows to show
61 $single_user = !&supports_users() || @ulist == 1;
62 @links = ( &select_all_link("d", 1),
63            &select_invert_link("d", 1),
64            @crlinks );
65 @rows = ( );
66 foreach $u (@ulist) {
67         if (!$config{'single_file'}) {
68                 # Get the Unix user's real name
69                 if ((@uinfo = getpwnam($u)) && $uinfo[5] =~ /\S/) {
70                         $uname = "$u ($uinfo[5])";
71                         }
72                 else { $uname = $u; }
73                 }
74
75         @jlist = grep { $_->{'user'} eq $u } @jobs;
76         @plist = ();
77         for($i=0; $i<@jlist; $i++) {
78                 local $rpd = &is_run_parts($jlist[$i]->{'command'});
79                 local @exp = $rpd ? &expand_run_parts($rpd) : ();
80                 if (!$rpd || @exp) {
81                         push(@plist, [ $jlist[$i], \@exp ]);
82                         }
83                 }
84         for($i=0; $i<@plist; $i++) {
85                 local $job = $plist[$i]->[0];
86                 &convert_range($job);
87                 &convert_comment($job);
88                 local @exp = @{$plist[$i]->[1]};
89                 local $idx = $job->{'index'};
90                 local @cols;
91                 push(@cols, $idx);
92                 $useridx = 0;
93                 $cmdidx = 0;
94                 if (!$single_user) {
95                         $useridx = scalar(@cols);
96                         push(@cols, &html_escape($uname));
97                         }
98                 push(@cols, $job->{'active'} ? $text{'yes'} :
99                                 "<font color=#ff0000>$text{'no'}</font>");
100                 $donelink = 0;
101                 if ($job->{'name'}) {
102                         # An environment variable - show the name only
103                         $cmdidx = scalar(@cols);
104                         push(@cols, "<a href=\"edit_env.cgi?idx=$idx\">".
105                                    "<i>$text{'index_env'}</i> ".
106                                    "<tt>$job->{'name'} = $job->{'value'}</tt>");
107                         $donelink = 1;
108                         }
109                 elsif (@exp && $access{'command'}) {
110                         # A multi-part command
111                         $cmdidx = scalar(@cols);
112                         @exp = map { &html_escape($_) } @exp;
113                         push(@cols, "<a href=\"edit_cron.cgi?idx=$idx\">".
114                                     join("<br>",@exp)."</a>");
115                         $donelink = 1;
116                         }
117                 elsif ($access{'command'}) {
118                         # A simple command
119                         $cmdidx = scalar(@cols);
120                         local $max = $config{'max_len'} || 10000;
121                         local ($cmd, $input) =
122                                 &extract_input($job->{'command'});
123                         $cmd = length($cmd) > $max ?
124                           &html_escape(substr($cmd, 0, $max))." ..." :
125                           $cmd !~ /\S/ ? "BLANK" : &html_escape($cmd);
126                         push(@cols,
127                              "<a href=\"edit_cron.cgi?idx=$idx\">$cmd</a>");
128                         $donelink = 1;
129                         }
130
131                 # Show cron time
132                 if (!$access{'command'} || $config{'show_time'} || $userconfig{'show_time'}) {
133                         $when = &when_text($job, 1);
134                         if ($job->{'name'}) {
135                                 push(@cols, "");
136                                 }
137                         elsif ($donelink) {
138                                 push(@cols, $when);
139                                 }
140                         else {
141                                 push(@cols,
142                                   "<a href='edit_cron.cgi?idx=$idx'>$when</a>");
143                                 }
144                         }
145
146                 # Show comment
147                 if ($config{'show_comment'} || $userconfig{'show_comment'}) {
148                         push(@cols, $job->{'comment'});
149                         }
150
151                 # Show running indicator
152                 if ($config{'show_run'}) {
153                         if ($job->{'name'}) {
154                                 # An environment variable
155                                 push(@cols, "");
156                                 }
157                         else {
158                                 # Try to find the process
159                                 local $proc = &find_cron_process($job, \@procs);
160                                 $txt = $proc ?
161                                     "<font color=#00aa00>$text{'yes'}</font>" :
162                                     $text{'no'};
163                                 if ($config{'show_run'} == 2 &&
164                                     ($access{'kill'} || !$proc)) {
165                                         $lnk = $proc ? "kill_cron.cgi?idx=$idx" : "exec_cron.cgi?idx=$idx&bg=1";
166                                         push(@cols, "<a href='$lnk'>$txt</a>");
167                                         }
168                                 else {
169                                         push(@cols, $txt);
170                                         }
171                                 }
172                         }
173
174                 # Show mover buttons
175                 local $prv = $i > 0 ? $plist[$i-1]->[0] : undef;
176                 local $nxt = $i != $#plist ? $plist[$i+1]->[0] : undef;
177                 if ($access{'move'}) {
178                         push(@cols, &ui_up_down_arrows(
179                                 "move.cgi?idx=$idx&up=1",
180                                 "move.cgi?idx=$idx&down=1",
181                                 $prv && $prv->{'file'} eq $job->{'file'} &&
182                                  ($job->{'type'} == 0 || $job->{'type'} == 3),
183                                 $nxt && $nxt->{'file'} eq $job->{'file'} &&
184                                  ($job->{'type'} == 0 || $job->{'type'} == 3)
185                                 ));
186                         }
187
188                 # Add search colume
189                 push(@cols, $job->{'command'}.' '.$job->{'name'}.' '.
190                             $job->{'comment'});
191                 push(@rows, \@cols);
192                 }
193         }
194
195 # Limit to search
196 if ($in{'search'}) {
197         @rows = grep { $_->[@$_-1] =~ /\Q$in{'search'}\E/i ||
198                        $_->[1] =~ /\Q$in{'search'}\E/i } @rows;
199         }
200
201 # Show search form
202 print &ui_form_start("index.cgi");
203 print "<b>$text{'index_search'}</b>\n";
204 print &ui_textbox("search", $in{'search'}, 20);
205 print &ui_submit($text{'index_ok'});
206 print &ui_form_end();
207
208 # Check if we are over the display limit
209 if ($max_jobs && @rows > $max_jobs && !$in{'search'}) {
210         print "<b>$text{'index_toomany2'}</b><p>\n";
211         print &ui_links_row(\@crlinks);
212         }
213 elsif (@rows) {
214         # Show jobs
215         if ($in{'search'}) {
216                 print "<b>",&text('index_searchres',
217                         "<i>".&html_escape($in{'search'})."</i>"),"</b><p>\n";
218                 push(@links, "<a href='index.cgi'>$text{'index_reset'}</a>");
219                 }
220         print &ui_form_start("delete_jobs.cgi", "post");
221         print &ui_links_row(\@links);
222         @tds = ( "width=5" );
223         print &ui_columns_start([
224                 "",
225                 $single_user ? ( ) : ( $text{'index_user'} ),
226                 $text{'index_active'},
227                 $access{'command'} ? ( $text{'index_command'} ) : ( ),
228                 !$access{'command'} || $config{'show_time'} ||
229                   $userconfig{'show_time'} ? ( $text{'index_when'} ) : ( ),
230                 $config{'show_comment'} || $userconfig{'show_comment'} ?
231                   ( $text{'index_comment'} ) : ( ),
232                 $config{'show_run'} ? ( $text{'index_run'} ) : ( ),
233                 $access{'move'} ? ( $text{'index_move'} ) : ( ),
234                 ], 100, 0, \@tds);
235         foreach my $r (@rows) {
236                 print &ui_checked_columns_row([ @$r[1..(@$r-2)] ],
237                                               \@tds, "d", $r->[0]);
238                 }
239         print &ui_columns_end();
240         print &ui_links_row(\@links);
241         print &ui_form_end([ [ "delete", $text{'index_delete'} ],
242                              [ "disable", $text{'index_disable'} ],
243                              [ "enable", $text{'index_enable'} ] ]);
244         }
245 else {
246         # Show message
247         if ($in{'search'}) {
248                 push(@crlinks, "<a href='index.cgi'>$text{'index_reset'}</a>");
249                 }
250         print $in{'search'} ? "<b>".&text('index_esearch',
251                         "<i>".&html_escape($in{'search'})."</i>")."</b> <p>" :
252               $module_info{'usermin'} ? "<b>$text{'index_none3'}</b> <p>\n" :
253               $access{'mode'} ? "<b>$text{'index_none2'}</b> <p>\n"
254                               : "<b>$text{'index_none'}</b> <p>\n";
255         print &ui_links_row(\@crlinks);
256         }
257
258 &ui_print_footer("/", $text{'index'});
259