* Split BackupPC_Admin into a set of modules, one for each major action.
[BackupPC.git] / lib / BackupPC / CGI / HostInfo.pm
1 #============================================================= -*-perl-*-
2 #
3 # BackupPC::CGI::HostInfo package
4 #
5 # DESCRIPTION
6 #
7 #   This module implements the HostInfo action for the CGI interface.
8 #
9 # AUTHOR
10 #   Craig Barratt  <cbarratt@users.sourceforge.net>
11 #
12 # COPYRIGHT
13 #   Copyright (C) 2003  Craig Barratt
14 #
15 #   This program is free software; you can redistribute it and/or modify
16 #   it under the terms of the GNU General Public License as published by
17 #   the Free Software Foundation; either version 2 of the License, or
18 #   (at your option) any later version.
19 #
20 #   This program is distributed in the hope that it will be useful,
21 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
22 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 #   GNU General Public License for more details.
24 #
25 #   You should have received a copy of the GNU General Public License
26 #   along with this program; if not, write to the Free Software
27 #   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28 #
29 #========================================================================
30 #
31 # Version 2.1.0_CVS, released 3 Jul 2003.
32 #
33 # See http://backuppc.sourceforge.net.
34 #
35 #========================================================================
36
37 package BackupPC::CGI::HostInfo;
38
39 use strict;
40 use BackupPC::CGI::Lib qw(:all);
41
42 sub action
43 {
44     my $host = $1 if ( $In{host} =~ /(.*)/ );
45     my($statusStr, $startIncrStr);
46
47     $host =~ s/^\s+//;
48     $host =~ s/\s+$//;
49     return Action_GeneralInfo() if ( $host eq "" );
50     $host = lc($host)
51                 if ( !-d "$TopDir/pc/$host" && -d "$TopDir/pc/" . lc($host) );
52     if ( $host =~ /\.\./ || !-d "$TopDir/pc/$host" ) {
53         #
54         # try to lookup by user name
55         #
56         if ( !defined($Hosts->{$host}) ) {
57             foreach my $h ( keys(%$Hosts) ) {
58                 if ( $Hosts->{$h}{user} eq $host
59                         || lc($Hosts->{$h}{user}) eq lc($host) ) {
60                     $host = $h;
61                     last;
62                 }
63             }
64             CheckPermission();
65             ErrorExit(eval("qq{$Lang->{Unknown_host_or_user}}"))
66                                 if ( !defined($Hosts->{$host}) );
67         }
68         $In{host} = $host;
69     }
70     GetStatusInfo("host(${EscURI($host)})");
71     $bpc->ConfigRead($host);
72     %Conf = $bpc->Conf();
73     my $Privileged = CheckPermission($host);
74     if ( !$Privileged ) {
75         ErrorExit(eval("qq{$Lang->{Only_privileged_users_can_view_information_about}}"));
76     }
77     ReadUserEmailInfo();
78
79     my @Backups = $bpc->BackupInfoRead($host);
80     my($str, $sizeStr, $compStr, $errStr, $warnStr);
81     for ( my $i = 0 ; $i < @Backups ; $i++ ) {
82         my $startTime = timeStamp2($Backups[$i]{startTime});
83         my $dur       = $Backups[$i]{endTime} - $Backups[$i]{startTime};
84         $dur          = 1 if ( $dur <= 0 );
85         my $duration  = sprintf("%.1f", $dur / 60);
86         my $MB        = sprintf("%.1f", $Backups[$i]{size} / (1024*1024));
87         my $MBperSec  = sprintf("%.2f", $Backups[$i]{size} / (1024*1024*$dur));
88         my $MBExist   = sprintf("%.1f", $Backups[$i]{sizeExist} / (1024*1024));
89         my $MBNew     = sprintf("%.1f", $Backups[$i]{sizeNew} / (1024*1024));
90         my($MBExistComp, $ExistComp, $MBNewComp, $NewComp);
91         if ( $Backups[$i]{sizeExist} && $Backups[$i]{sizeExistComp} ) {
92             $MBExistComp = sprintf("%.1f", $Backups[$i]{sizeExistComp}
93                                                 / (1024 * 1024));
94             $ExistComp = sprintf("%.1f%%", 100 *
95                   (1 - $Backups[$i]{sizeExistComp} / $Backups[$i]{sizeExist}));
96         }
97         if ( $Backups[$i]{sizeNew} && $Backups[$i]{sizeNewComp} ) {
98             $MBNewComp = sprintf("%.1f", $Backups[$i]{sizeNewComp}
99                                                 / (1024 * 1024));
100             $NewComp = sprintf("%.1f%%", 100 *
101                   (1 - $Backups[$i]{sizeNewComp} / $Backups[$i]{sizeNew}));
102         }
103         my $age = sprintf("%.1f", (time - $Backups[$i]{startTime}) / (24*3600));
104         my $browseURL = "$MyURL?action=browse&host=${EscURI($host)}&num=$Backups[$i]{num}";
105         my $filled = $Backups[$i]{noFill} ? $Lang->{No} : $Lang->{Yes};
106         $filled .= " ($Backups[$i]{fillFromNum}) "
107                             if ( $Backups[$i]{fillFromNum} ne "" );
108         my $ltype;
109         if ($Backups[$i]{type} eq "full") { $ltype = $Lang->{full}; }
110         else { $ltype = $Lang->{incremental}; }
111         $str .= <<EOF;
112 <tr><td align="center"> <a href="$browseURL">$Backups[$i]{num}</a> </td>
113     <td align="center"> $ltype </td>
114     <td align="center"> $filled </td>
115     <td align="right">  $startTime </td>
116     <td align="right">  $duration </td>
117     <td align="right">  $age </td>
118     <td align="left">   <tt>$TopDir/pc/$host/$Backups[$i]{num}</tt> </td></tr>
119 EOF
120         $sizeStr .= <<EOF;
121 <tr><td align="center"> <a href="$browseURL">$Backups[$i]{num}</a> </td>
122     <td align="center"> $ltype </td>
123     <td align="right">  $Backups[$i]{nFiles} </td>
124     <td align="right">  $MB </td>
125     <td align="right">  $MBperSec </td>
126     <td align="right">  $Backups[$i]{nFilesExist} </td>
127     <td align="right">  $MBExist </td>
128     <td align="right">  $Backups[$i]{nFilesNew} </td>
129     <td align="right">  $MBNew </td>
130 </tr>
131 EOF
132         my $is_compress = $Backups[$i]{compress} || $Lang->{off};
133         if (! $ExistComp) { $ExistComp = "&nbsp;"; }
134         if (! $MBExistComp) { $MBExistComp = "&nbsp;"; }
135         $compStr .= <<EOF;
136 <tr><td align="center"> <a href="$browseURL">$Backups[$i]{num}</a> </td>
137     <td align="center"> $ltype </td>
138     <td align="center"> $is_compress </td> 
139     <td align="right">  $MBExist </td>
140     <td align="right">  $MBExistComp </td> 
141     <td align="right">  $ExistComp </td>   
142     <td align="right">  $MBNew </td>
143     <td align="right">  $MBNewComp </td>
144     <td align="right">  $NewComp </td>
145 </tr>
146 EOF
147         $errStr .= <<EOF;
148 <tr><td align="center"> <a href="$browseURL">$Backups[$i]{num}</a> </td>
149     <td align="center"> $ltype </td>
150     <td align="center"> <a href="$MyURL?action=view&type=XferLOG&num=$Backups[$i]{num}&host=${EscURI($host)}">$Lang->{XferLOG}</a>,
151                       <a href="$MyURL?action=view&type=XferErr&num=$Backups[$i]{num}&host=${EscURI($host)}">$Lang->{Errors}</a> </td>
152     <td align="right">  $Backups[$i]{xferErrs} </td>
153     <td align="right">  $Backups[$i]{xferBadFile} </td>
154     <td align="right">  $Backups[$i]{xferBadShare} </td>
155     <td align="right">  $Backups[$i]{tarErrs} </td></tr>
156 EOF
157     }
158
159     my @Restores = $bpc->RestoreInfoRead($host);
160     my $restoreStr;
161
162     for ( my $i = 0 ; $i < @Restores ; $i++ ) {
163         my $startTime = timeStamp2($Restores[$i]{startTime});
164         my $dur       = $Restores[$i]{endTime} - $Restores[$i]{startTime};
165         $dur          = 1 if ( $dur <= 0 );
166         my $duration  = sprintf("%.1f", $dur / 60);
167         my $MB        = sprintf("%.1f", $Restores[$i]{size} / (1024*1024));
168         my $MBperSec  = sprintf("%.2f", $Restores[$i]{size} / (1024*1024*$dur));
169         my $Restores_Result = $Lang->{failed};
170         if ($Restores[$i]{result} ne "failed") { $Restores_Result = $Lang->{success}; }
171         $restoreStr  .= <<EOF;
172 <tr><td align="center"><a href="$MyURL?action=restoreInfo&num=$Restores[$i]{num}&host=${EscURI($host)}">$Restores[$i]{num}</a> </td>
173     <td align="center"> $Restores_Result </td>
174     <td align="right"> $startTime </td>
175     <td align="right"> $duration </td>
176     <td align="right"> $Restores[$i]{nFiles} </td>
177     <td align="right"> $MB </td>
178     <td align="right"> $Restores[$i]{tarCreateErrs} </td>
179     <td align="right"> $Restores[$i]{xferErrs} </td>
180 </tr>
181 EOF
182     }
183     if ( $restoreStr ne "" ) {
184         $restoreStr = eval("qq{$Lang->{Restore_Summary}}");
185     }
186     if ( @Backups == 0 ) {
187         $warnStr = $Lang->{This_PC_has_never_been_backed_up};
188     }
189     if ( defined($Hosts->{$host}) ) {
190         my $user = $Hosts->{$host}{user};
191         my @moreUsers = sort(keys(%{$Hosts->{$host}{moreUsers}}));
192         my $moreUserStr;
193         foreach my $u ( sort(keys(%{$Hosts->{$host}{moreUsers}})) ) {
194             $moreUserStr .= ", " if ( $moreUserStr ne "" );
195             $moreUserStr .= "${UserLink($u)}";
196         }
197         if ( $moreUserStr ne "" ) {
198             $moreUserStr = " ($Lang->{and} $moreUserStr).\n";
199         } else {
200             $moreUserStr = ".\n";
201         }
202         if ( $user ne "" ) {
203             $statusStr .= eval("qq{$Lang->{This_PC_is_used_by}$moreUserStr}");
204         }
205         if ( defined($UserEmailInfo{$user})
206                 && $UserEmailInfo{$user}{lastHost} eq $host ) {
207             my $mailTime = timeStamp2($UserEmailInfo{$user}{lastTime});
208             my $subj     = $UserEmailInfo{$user}{lastSubj};
209             $statusStr  .= eval("qq{$Lang->{Last_email_sent_to__was_at___subject}}");
210         }
211     }
212     if ( defined($Jobs{$host}) ) {
213         my $startTime = timeStamp2($Jobs{$host}{startTime});
214         (my $cmd = $Jobs{$host}{cmd}) =~ s/$BinDir\///g;
215         $statusStr .= eval("qq{$Lang->{The_command_cmd_is_currently_running_for_started}}");
216     }
217     if ( $StatusHost{BgQueueOn} ) {
218         $statusStr .= eval("qq{$Lang->{Host_host_is_queued_on_the_background_queue_will_be_backed_up_soon}}");
219     }
220     if ( $StatusHost{UserQueueOn} ) {
221         $statusStr .= eval("qq{$Lang->{Host_host_is_queued_on_the_user_queue__will_be_backed_up_soon}}");
222     }
223     if ( $StatusHost{CmdQueueOn} ) {
224         $statusStr .= eval("qq{$Lang->{A_command_for_host_is_on_the_command_queue_will_run_soon}}");
225     }
226     my $startTime = timeStamp2($StatusHost{endTime} == 0 ?
227                 $StatusHost{startTime} : $StatusHost{endTime});
228     my $reason = "";
229     if ( $StatusHost{reason} ne "" ) {
230         $reason = " ($Lang->{$StatusHost{reason}})";
231     }
232     $statusStr .= eval("qq{$Lang->{Last_status_is_state_StatusHost_state_reason_as_of_startTime}}");
233
234     if ( $StatusHost{state} ne "Status_backup_in_progress"
235             && $StatusHost{state} ne "Status_restore_in_progress"
236             && $StatusHost{error} ne "" ) {
237         $statusStr .= eval("qq{$Lang->{Last_error_is____EscHTML_StatusHost_error}}");
238     }
239     my $priorStr = "Pings";
240     if ( $StatusHost{deadCnt} > 0 ) {
241         $statusStr .= eval("qq{$Lang->{Pings_to_host_have_failed_StatusHost_deadCnt__consecutive_times}}");
242         $priorStr = $Lang->{Prior_to_that__pings};
243     }
244     if ( $StatusHost{aliveCnt} > 0 ) {
245         $statusStr .= eval("qq{$Lang->{priorStr_to_host_have_succeeded_StatusHostaliveCnt_consecutive_times}}");
246
247         if ( $StatusHost{aliveCnt} >= $Conf{BlackoutGoodCnt}
248                 && $Conf{BlackoutGoodCnt} >= 0 && $Conf{BlackoutHourBegin} >= 0
249                 && $Conf{BlackoutHourEnd} >= 0 ) {
250             my(@days) = qw(Sun Mon Tue Wed Thu Fri Sat);
251             my($days) = join(", ", @days[@{$Conf{BlackoutWeekDays}}]);
252             my($t0) = sprintf("%d:%02d", $Conf{BlackoutHourBegin},
253                             60 * ($Conf{BlackoutHourBegin}
254                                      - int($Conf{BlackoutHourBegin})));
255             my($t1) = sprintf("%d:%02d", $Conf{BlackoutHourEnd},
256                             60 * ($Conf{BlackoutHourEnd}
257                                      - int($Conf{BlackoutHourEnd})));
258             $statusStr .= eval("qq{$Lang->{Because__host_has_been_on_the_network_at_least__Conf_BlackoutGoodCnt_consecutive_times___}}");
259         }
260     }
261     if ( $StatusHost{backoffTime} > time ) {
262         my $hours = sprintf("%.1f", ($StatusHost{backoffTime} - time) / 3600);
263         $statusStr .= eval("qq{$Lang->{Backups_are_deferred_for_hours_hours_change_this_number}}");
264
265     }
266     if ( @Backups ) {
267         # only allow incremental if there are already some backups
268         $startIncrStr = <<EOF;
269 <input type="submit" value="\$Lang->{Start_Incr_Backup}" name="action">
270 EOF
271     }
272
273     $startIncrStr = eval ("qq{$startIncrStr}");
274
275     Header(eval("qq{$Lang->{Host__host_Backup_Summary}}"));
276     print(eval("qq{$Lang->{Host__host_Backup_Summary2}}"));
277     Trailer();
278 }
279
280 1;