Handle hostnames with upper-case letters
[webmin.git] / custom / run.cgi
1 #!/usr/local/bin/perl
2 # run.cgi
3 # Run some command with the given parameters
4
5 require './custom-lib.pl';
6 $theme_no_table = 1;
7 if ($ENV{'CONTENT_TYPE'} =~ /multipart\/form-data/i) {
8         &ReadParse(\%getin, "GET");
9         &ReadParseMime(undef, \&read_parse_mime_callback, [ $getin{'id'} ]);
10         }
11 else {
12         &ReadParse();
13         }
14 $| = 1;
15 &error_setup($text{'run_err'});
16 $cmd = &get_command($in{'id'}, $in{'idx'});
17 &can_run_command($cmd) || &error($text{'run_ecannot'});
18 if (&supports_users()) {
19         $user = $cmd->{'user'} eq '*' ? $remote_user : $cmd->{'user'};
20         @user_info = getpwnam($user);
21         @user_info || &error(&text('run_ecmduser', $user));
22         }
23 else {
24         @user_info = ( "root", undef, 0, 0 );
25         }
26
27 # substitute parameters into command
28 ($env, $export, $str, $displaystr) = &set_parameter_envs(
29                                         $cmd, $cmd->{'cmd'}, \@user_info);
30
31 # work out hosts
32 @hosts = @{$cmd->{'hosts'}};
33 @hosts = ( 0 ) if (!@hosts);
34 @servers = &list_servers();
35
36 # Run and display output
37 if ($cmd->{'format'} ne 'redirect') {
38         if ($cmd->{'format'}) {
39                 print "Content-type: ",$cmd->{'format'},"\n";
40                 print "\n";
41                 }
42         else {
43                 &ui_print_unbuffered_header($cmd->{'desc'}, $text{'run_title'},
44                                             "", -d "help" ? "run" : undef);
45                 }
46         }
47
48 &remote_error_setup(\&remote_custom_handler);
49
50 foreach $h (@hosts) {
51         ($server) = grep { $_->{'id'} eq $h } @servers;
52         next if (!$server);
53         $txt = $cmd->{'noshow'} ? 'run_out2' : 'run_out';
54         if (@{$cmd->{'hosts'}}) {
55                 $txt .= 'on';
56                 }
57         if (!$cmd->{'format'}) {
58                 print &text($txt, "<tt>".&html_escape($displaystr)."</tt>",
59                     $server->{'desc'} || "<tt>$server->{'host'}</tt>"),"\n";
60                 print "<pre>" if (!$cmd->{'raw'});
61                 }
62         $remote_custom_error = undef;
63         if ($h == 0) {
64                 # Run locally
65                 ($got, $out, $timeout) = &execute_custom_command(
66                                         $cmd, $env, $export, $str,
67                                         $cmd->{'format'} ne 'redirect');
68                 }
69         else {
70                 # Remote foreign call
71                 &remote_foreign_require($server->{'host'}, "custom",
72                                         "custom-lib.pl");
73                 &remote_foreign_call($server->{'host'}, "custom",
74                                      "set_parameter_envs", $cmd, $cmd->{'cmd'},
75                                      \@user_info, \%in, 1);
76                 ($got, $out, $timeout) = &remote_foreign_call(
77                         $server->{'host'}, "custom", "execute_custom_command",
78                         $cmd, $env, $export, $str);
79                 }
80         if ($h == 0) {
81                 &additional_log('exec', undef, $displaystr);
82                 }
83         if (!$remote_custom_error) {
84                 print $out if ($h != 0 && $cmd->{'format'} ne 'redirect');
85                 if (!$got && !$cmd->{'format'}) {
86                         print "<i>$text{'run_noout'}</i>\n";
87                         }
88                 }
89
90         if (!$cmd->{'format'}) {
91                 print "</pre>\n" if (!$cmd->{'raw'});
92                 if ($remote_custom_error) {
93                         print "<b>$remote_custom_error</b><p>\n";
94                         }
95                 elsif ($timeout) {
96                         print "<b>",&text('run_timeout',
97                                           $cmd->{'timeout'}),"</b><p>\n";
98                         }
99                 }
100
101         # Only log non-upload inputs
102         %cmdin = ( %$cmd );
103         foreach $i (keys %in) {
104                 ($arg) = grep { $_->{'name'} eq $i } @{$cmd->{'args'}};
105                 if ($arg->{'type'} != 10) {
106                         $cmdin{$i} = $in{$i};
107                         }
108                 }
109         }
110 &webmin_log("exec", "command", $cmd->{'id'}, \%cmdin);
111 unlink(@unlink) if (@unlink);
112 if (!$cmd->{'format'}) {
113         &ui_print_footer("", $text{'index_return'});
114         }
115 elsif ($cmd->{'format'} eq 'redirect') {
116         &redirect("");
117         }
118
119 sub remote_custom_handler
120 {
121 $remote_custom_error = join("", @_);
122 }
123