Handle hostnames with upper-case letters
[webmin.git] / webminlog / rollback.cgi
1 #!/usr/local/bin/perl
2 # rollback.cgi
3 # Revert all changed config files, after asking for confirmation
4
5 use strict;
6 use warnings;
7 require './webminlog-lib.pl';
8 our (%text, %in, %access);
9 &ReadParse();
10 my $act = &get_action($in{'id'});
11
12 if ($in{'annosave'}) {
13         # Just saving an annotation
14         $in{'anno'} =~ s/\r//g;
15         &save_annotation($act, $in{'anno'});
16         &redirect("view.cgi?id=$in{'id'}&search=".&urlize($in{'search'}));
17         exit;
18         }
19
20 $access{'rollback'} ||  &error($text{'rollback_ecannot'});
21 &can_user($act->{'user'}) || &error($text{'view_ecannot'});
22 &can_mod($act->{'module'}) || &error($text{'view_ecannot'});
23 my %r = map { $_, 1 } split(/\0/, $in{'r'});
24 %r || &error($text{'rollback_enone'});
25 my @files = grep { $r{$_->{'file'}} } &list_files($act);
26
27 &ui_print_header(undef, $text{'rollback_title'}, "");
28 if ($in{'confirm'}) {
29         # Do it!
30         my %done;
31         foreach my $f (@files) {
32                 next if ($done{$f->{'file'}});
33                 if (-d $f->{'file'} || $f->{'type'} == 1) {
34                         # Skip directory
35                         print &text('rollback_skipdir',"<tt>$f->{'file'}</tt>");
36                         }
37                 elsif (-l $f->{'file'} && $f->{'type'} == 2 ||
38                        !-e $f->{'file'} && $f->{'type'} == 2 ||
39                        !-l $f->{'file'} && $f->{'type'} == 2) {
40                         # Modify or create link
41                         &lock_file($f->{'file'});
42                         &unlink_file($f->{'file'});
43                         &symlink_file($f->{'data'}, $f->{'file'});
44                         &unlock_file($f->{'file'});
45                         print &text('rollback_madelink',
46                                     "<tt>$f->{'file'}</tt>",
47                                     "<tt>$f->{'data'}</tt>");
48                         }
49                 elsif (-e $f->{'file'} && -l $f->{'file'} &&
50                        $f->{'type'} == 0) {
51                         # Remove link and create file
52                         &lock_file($f->{'file'});
53                         &unlink_file($f->{'file'});
54                         my $fh;
55                         &open_tempfile($fh, ">$f->{'file'}");
56                         &print_tempfile($fh, $f->{'data'});
57                         &close_tempfile($fh);
58                         &unlock_file($f->{'file'});
59                         print &text('rollback_madefile',
60                                     "<tt>$f->{'file'}</tt>");
61                         }
62                 elsif ($f->{'type'} == -1) {
63                         if (-e $f->{'file'}) {
64                                 # Remove file
65                                 &unlink_logged($f->{'file'});
66                                 print &text('rollback_deleted',
67                                             "<tt>$f->{'file'}</tt>");
68                                 }
69                         else {
70                                 print &text('rollback_nodeleted',
71                                             "<tt>$f->{'file'}</tt>");
72                                 }
73                         }
74                 else {
75                         # Replace file with old contents
76                         my $fh;
77                         &open_lock_tempfile($fh, ">$f->{'file'}");
78                         &print_tempfile($fh, $f->{'data'});
79                         &close_tempfile($fh);
80                         print &text('rollback_modfile',
81                                     "<tt>$f->{'file'}</tt>");
82                         }
83                 print "<br>\n";
84                 $done{$f->{'file'}}++;
85                 }
86         my %minfo = &get_module_info($act->{'module'});
87         &webmin_log("rollback", undef, $in{'id'},
88                     { 'desc' => &get_action_description($act),
89                       'mdesc' => $minfo{'desc'} });
90         }
91 else {
92         # Show the user what will be done
93         print &ui_form_start("rollback.cgi");
94         print &ui_hidden("id", $in{'id'});
95         print &ui_hidden("search", $in{'search'});
96         foreach my $r (keys %r) {
97                 print &ui_hidden("r", $r);
98                 }
99         print $text{'rollback_rusure'},"<p>\n";
100         my %done;
101         my $count = 0;
102         foreach my $f (@files) {
103                 next if ($done{$f->{'file'}});
104                 print &ui_table_start("<tt>$f->{'file'}</tt>", "width=100%", 2);
105                 print "<tr> <td colspan=2>";
106                 if (-d $f->{'file'} || $f->{'type'} == 1) {
107                         # Is a directory
108                         print &text('rollback_isdir');
109                         }
110                 elsif (-l $f->{'file'} && $f->{'type'} == 2 ||
111                        !-e $f->{'file'} && $f->{'type'} == 2) {
112                         # Was a link, and is one now
113                         my $lnk = readlink($f->{'file'});
114                         if (!-e $f->{'file'}) {
115                                 print &text('rollback_clink', "<tt>$f->{'data'}</tt>");
116                                 $count++;
117                                 }
118                         elsif ($lnk ne $f->{'data'}) {
119                                 print &text('rollback_link', "<tt>$f->{'data'}</tt>", "<tt>$lnk</tt>");
120                                 $count++;
121                                 }
122                         else {
123                                 print &text('rollback_nolink');
124                                 }
125                         }
126                 elsif (-e $f->{'file'} && -l $f->{'file'} &&
127                        $f->{'type'} == 0) {
128                         # Was a file, but is now a link
129                         my $lnk = readlink($f->{'file'});
130                         print &text('rollback_makefile', "<tt>$lnk</tt>");
131                         print "<pre>$f->{'data'}</pre>";
132                         $count++;
133                         }
134                 elsif (!-l $f->{'file'} && $f->{'type'} == 2) {
135                         # Was a link, but is now a file
136                         print &text('rollback_makelink', "<tt>$f->{'data'}</tt>");
137                         $count++;
138                         }
139                 elsif ($f->{'type'} == -1) {
140                         # Was created
141                         if (-e $f->{'file'}) {
142                                 print &text('rollback_delete',
143                                             "<tt>$f->{'file'}</tt>");
144                                 $count++;
145                                 }
146                         else {
147                                 print &text('rollback_nodelete',
148                                             "<tt>$f->{'file'}</tt>");
149                                 }
150                         }
151                 elsif (!-e $f->{'file'}) {
152                         # No longer exists
153                         print $text{'rollback_fillfile'};
154                         print "<pre>$f->{'data'}</pre>";
155                         $count++;
156                         }
157                 else {
158                         # Was a file, and is one now
159                         my $qnew = quotemeta($f->{'file'});
160                         my $temp = &transname();
161                         open(TEMP, ">$temp");
162                         print TEMP $f->{'data'};
163                         close(TEMP);
164                         my $out = &backquote_command("diff $qnew $temp");
165                         if ($out) {
166                                 print $text{'rollback_changes'};
167                                 print "<pre>$out</pre>";
168                                 $count++;
169                                 }
170                         else {
171                                 print $text{'rollback_nochanges'};
172                                 }
173                         }
174                 $done{$f->{'file'}}++;
175                 print "</td> </tr>\n";
176                 print &ui_table_end();
177                 print "<br>\n";
178                 }
179         if ($count) {
180                 print &ui_form_end([ [ "confirm", $text{'rollback_ok'} ] ]);
181                 }
182         else {
183                 print "<b>$text{'rollback_none'}</b>\n";
184                 print &ui_form_end();
185                 }
186         }
187 &ui_print_footer("view.cgi?id=$in{'id'}&search=".&urlize($in{'search'}),
188                   $text{'view_return'},
189                  "", $text{'index_return'});
190
191