Handle hostnames with upper-case letters
[webmin.git] / bacula-backup / restore.cgi
1 #!/usr/local/bin/perl
2 # Actually execute the restore
3
4 require './bacula-backup-lib.pl';
5 &ReadParse();
6 &error_setup($text{'restore_err'});
7 $dbh = &connect_to_database();
8
9 # Validate inputs
10 @files = split(/\r?\n/, $in{'files'});
11 @files || &error($text{'restore_efiles'});
12 $in{'where'} =~ s/\\/\//g;
13 $in{'where_def'} || $in{'where'} =~ /^([a-z]:)?\// ||
14         &error($text{'restore_ewhere'});
15 $in{'client'} || &error($text{'restore_eclient'});
16 if ($in{'job'} =~ /^nj_(.*)_(\d+)_(\d+)$/) {
17         # Node group job restore ..
18         $in{'client'} eq "*" || &error($text{'restore_eall1'});
19         $name = $1;
20         $time = $2;
21         }
22 else {
23         # Single job restore
24         $in{'client'} eq "*" && &error($text{'restore_eall2'});
25
26         # Get the job name
27         $cmd = $dbh->prepare("select Name from Job where JobId = ?");
28         $cmd->execute($in{'job'});
29         ($name) = $cmd->fetchrow();
30         $cmd->finish();
31         }
32
33 # Work out clients to restore to
34 if ($in{'client'} eq "*") {
35         # Clients that were originally backed up
36         $cmd = $dbh->prepare("select Job.JobId,Job.Name,Job.SchedTime,Client.Name from Job,Client where Job.Name not like 'Restore%' and Job.ClientId = Client.ClientId order by SchedTime desc");
37         $cmd->execute();
38         while(my ($jid, $jname, $jwhen, $jclient) = $cmd->fetchrow()) {
39                 ($j, $c) = &is_oc_object($jname);
40                 $stime = &date_to_unix($jwhen);
41                 if ($j && $c && $j eq $name) {
42                         if (abs($stime - $time) < 30) {
43                                 # Found a member of the group
44                                 push(@clients, [ $jclient, $jid ]);
45                                 }
46                         }
47                 }
48         $cmd->finish();
49         @clients || &error($text{'restore_eclients'});
50         &ui_print_unbuffered_header(undef,  $text{'restore_title3'}, "", "restore");
51         }
52 elsif ($g = &is_oc_object($in{'client'})) {
53         # All clients in a node group
54         ($group) = grep { $_->{'name'} eq $g } &list_node_groups();
55         $group || &error($text{'restore_egroup'});
56         @clients = map { [ "occlient_${g}_".$_, $in{'job'} ] } @{$group->{'members'}};
57         &ui_print_unbuffered_header(undef,  $text{'restore_title2'}, "", "restore");
58         }
59 else {
60         # Just one
61         &ui_print_unbuffered_header(undef,  $text{'restore_title'}, "", "restore");
62         @clients = ( [ $in{'client'}, $in{'job'} ] );
63         }
64
65 foreach $clientjob (@clients) {
66         $client = $clientjob->[0];
67         $job = $clientjob->[1];
68         ($g, $c) = &is_oc_object($name);
69         ($gc, $cc) = &is_oc_object($client);
70         print "<b>",&text('restore_run', $c ? "<tt>$c</tt>" : "<tt>$name</tt>", $cc ? "<tt>$cc</tt>" : "<tt>$client</tt>", "<tt>$in{'storage'}</tt>"),"</b>\n";
71         print "<pre>";
72         $h = &open_console();
73
74         # Clear messages
75         &console_cmd($h, "messages");
76
77         # Start the restore process
78         &sysprint($h->{'infh'}, "restore client=$client jobid=$job storage=$in{'storage'}".($in{'where_def'} ? "" : " where=\"$in{'where'}\"")."\n");
79         &wait_for($h->{'outfh'}, 'restore.*\n');
80         print $wait_for_input;
81         $rv = &wait_for($h->{'outfh'}, 'Enter\s+"done".*\n',
82                                        'Unable to get Job record',
83                                        'all the files');
84         print $wait_for_input;
85         if ($rv == 1) {
86                 &job_error($text{'restore_ejob'});
87                 }
88         elsif ($rv == 2) {
89                 &job_error($text{'restore_ejobfiles'});
90                 }
91
92         # Select the files
93         foreach $f (@files) {
94                 $f = &unix_to_dos($f);
95                 if ($f eq "/") {
96                         &sysprint($h->{'infh'}, "cd /\n");
97                         &wait_for($h->{'outfh'}, "\\\$");
98                         print $wait_for_input;
99
100                         &sysprint($h->{'infh'}, "mark *\n");
101                         &wait_for($h->{'outfh'}, "\\\$");
102                         print $wait_for_input;
103                         }
104                 elsif ($f =~ /^(.*)\/([^\/]+)\/?$/) {
105                         local ($fd, $ff) = ($1, $2);
106                         $fd ||= "/";
107                         &sysprint($h->{'infh'}, "cd \"$fd\"\n");
108                         &wait_for($h->{'outfh'}, "\\\$");
109                         print $wait_for_input;
110
111                         &sysprint($h->{'infh'}, "mark \"$ff\"\n");
112                         &wait_for($h->{'outfh'}, "\\\$");
113                         print $wait_for_input;
114                         }
115                 }
116         &sysprint($h->{'infh'}, "done\n");
117         $rv = &wait_for($h->{'outfh'}, 'OK to run.*:', 'no files selected');
118         print $wait_for_input;
119         if ($rv == 0) {
120                 &sysprint($h->{'infh'}, "yes\n");
121                 }
122         elsif ($rv == 1) {
123                 &job_error($text{'restore_enofiles'});
124                 }
125         else {
126                 &job_error($text{'backup_eok'});
127                 }
128         print "</pre>\n";
129
130         if ($in{'wait'}) {
131                 # Wait till we have a status
132                 print "</pre>\n";
133                 print "<b>",$text{'restore_running'},"</b>\n";
134                 print "<pre>";
135                 while(1) {
136                         $out = &console_cmd($h, "messages");
137                         if ($out !~ /You\s+have\s+no\s+messages/i) {
138                                 print $out;
139                                 }
140                         if ($out =~ /Termination:\s+(.*)/) {
141                                 $status = $1;
142                                 last;
143                                 }
144                         sleep(1);
145                         }
146                 print "</pre>\n";
147                 if ($status =~ /Restore\s+OK/i && $status !~ /warning/i) {
148                         print "<b>",$text{'restore_done'},"</b><p>\n";
149                         }
150                 else {
151                         print "<b>",$text{'restore_failed'},"</b><p>\n";
152                         }
153                 }
154         else {
155                 # Let it fly
156                 print "<b>",$text{'restore_running2'},"</b><p>\n";
157                 }
158
159         &close_console($h);
160         }
161
162 &webmin_log("restore", $in{'job'});
163
164 &ui_print_footer("restore_form.cgi", $text{'restore_return'});
165
166 sub job_error
167 {
168 &close_console($h);
169 print "</pre>\n";
170 print "<b>",@_,"</b><p>\n";
171 &ui_print_footer("backup_form.cgi", $text{'backup_return'});
172 exit;
173 }
174