890ba5104e2a557b3022eb2dd9ed931c80f202ea
[BackupPC.git] / lib / BackupPC / CGI / Archive.pm
1 #============================================================= -*-perl-*-
2 #
3 # BackupPC::CGI::Archive package
4 #
5 # DESCRIPTION
6 #
7 #   This module implements the Archive action for the CGI interface.
8 #
9 # AUTHOR
10 #   Craig Barratt  <cbarratt@users.sourceforge.net>
11 #
12 # COPYRIGHT
13 #   Copyright (C) 2003-2007  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 3.2.0beta0, released 5 April 2009.
32 #
33 # See http://backuppc.sourceforge.net.
34 #
35 #========================================================================
36
37 package BackupPC::CGI::Archive;
38
39 use strict;
40 use BackupPC::CGI::Lib qw(:all);
41 use Data::Dumper;
42
43 sub action
44 {
45     my $archHost = $In{host};
46     my $Privileged = CheckPermission();
47
48     if ( !$Privileged ) {
49         ErrorExit($Lang->{Only_privileged_users_can_archive} );
50     }
51     if ( $In{type} == 0 ) {
52         my($fullTot, $fullSizeTot, $incrTot, $incrSizeTot, $str,
53            $strNone, $strGood, $hostCntGood, $hostCntNone, $checkBoxCnt,
54            $backupnumber);
55
56         $hostCntGood = $hostCntNone = $checkBoxCnt = $fullSizeTot = 0;
57         GetStatusInfo("hosts");
58
59         foreach my $host ( sort(keys(%Status)) ) {
60             my($fullDur, $incrCnt, $fullSize, $fullRate);
61             my @Backups = $bpc->BackupInfoRead($host);
62             my $fullCnt = $incrCnt = 0;
63             for ( my $i = 0 ; $i < @Backups ; $i++ ) {
64                 if ( $Backups[$i]{type} eq "full" ) {
65                     $fullSize = $Backups[$i]{size} / (1024 * 1024);
66                     $incrSizeTot = 0;
67                 } else {
68                     $incrSizeTot = $Backups[$i]{size} / (1024 * 1024);
69                 }
70                 $backupnumber = $Backups[$i]{num};
71             }
72             $fullSizeTot += $fullSize + $incrSizeTot;
73             $fullSize = sprintf("%.2f", ($fullSize + $incrSizeTot) / 1000);
74             $str = <<EOF;
75 <tr>
76 <td class="border"><input type="hidden" name="backup$checkBoxCnt" value="$backupnumber"><input type="checkbox" name="fcb$checkBoxCnt" value="$host">&nbsp;${HostLink($host)} </td>
77 <td align="center" class="border"> ${UserLink($Hosts->{$host}{user})} </td>
78 <td align="center" class="border"> $fullSize </td>
79 EOF
80             $checkBoxCnt++;
81             if ( @Backups == 0 ) {
82                 $hostCntNone++;
83                 $strNone .= $str;
84             } else {
85                 $hostCntGood++;
86                 $strGood .= $str;
87             }
88         }
89         $fullSizeTot = sprintf("%.2f", $fullSizeTot / 1000);
90         my $now      = timeStamp2(time);
91         my $checkAllHosts = $Lang->{checkAllHosts};
92         $strGood .= <<EOF;
93 <input type="hidden" name="archivehost" value="$In{'archivehost'}">
94 EOF
95         my $content = eval("qq{$Lang->{BackupPC_Archive}}");
96         Header(eval("qq{$Lang->{BackupPC__Archive}}"), $content, 1);
97         Trailer();
98     } else {
99         my(@HostList, @BackupList, $HostListStr, $hiddenStr, $pathHdr,
100            $badFileCnt, $reply, $str);
101
102         #
103         # Pick up the archive host's config file
104         #
105         $bpc->ConfigRead($archHost);
106         %Conf = $bpc->Conf();
107
108         my $args = {
109             SplitPath    => $Conf{SplitPath},
110             ParPath      => $Conf{ParPath},
111             CatPath      => $Conf{CatPath},
112             GzipPath     => $Conf{GzipPath},
113             Bzip2Path    => $Conf{Bzip2Path},
114             ArchiveDest  => $Conf{ArchiveDest},
115             ArchiveComp  => $Conf{ArchiveComp},
116             ArchivePar   => $Conf{ArchivePar},
117             ArchiveSplit => $Conf{ArchiveSplit},
118             topDir       => $bpc->{TopDir},
119         };
120
121         ServerConnect();
122
123         for ( my $i = 0 ; $i < $In{fcbMax} ; $i++ ) {
124             next if ( !defined($In{"fcb$i"}) );
125             my $name = $In{"fcb$i"};
126             my $backupno = $In{"backup$i"};
127             push(@HostList, $name);
128             push(@BackupList, $backupno);
129             $hiddenStr .= <<EOF;
130 <input type="hidden" name="fcb$i" value="$In{'fcb' . $i}">
131 <input type="hidden" name="backup$i" value="$In{'backup' . $i}">
132 EOF
133             $HostListStr .= <<EOF;
134 <li> ${EscHTML($name)}
135 EOF
136         }
137         $hiddenStr .= <<EOF;
138 <input type="hidden" name="archivehost" value="$In{'archivehost'}">
139 EOF
140         $hiddenStr .= "<input type=\"hidden\" name=\"fcbMax\" value=\"$In{fcbMax}\">\n";
141         if ( @HostList == 0 ) {
142             ErrorExit($Lang->{You_haven_t_selected_any_hosts});
143         }
144         my ($ArchiveDest, $ArchiveCompNone, $ArchiveCompGzip,
145             $ArchiveCompBzip2, $ArchivePar, $ArchiveSplit);
146         $ArchiveDest = $Conf{ArchiveDest};
147         if ( $Conf{ArchiveComp} eq "none" ) {
148             $ArchiveCompNone   = "checked";
149         } else {
150             $ArchiveCompNone   = "";
151         }
152         if ( $Conf{ArchiveComp} eq "gzip" ) {
153             $ArchiveCompGzip   = "checked";
154         } else {
155             $ArchiveCompGzip   = "";
156         }
157         if ( $Conf{ArchiveComp} eq "bzip2" ) {
158             $ArchiveCompBzip2  = "checked";
159         } else {
160             $ArchiveCompBzip2  = "";
161         }
162         $ArchivePar   = $Conf{ArchivePar};
163         $ArchiveSplit = $Conf{ArchiveSplit};
164
165         if ( $In{type} == 1 ) {
166             #
167             # Tell the user what options they have
168             #
169             my $paramStr = "";
170             if ( $Conf{ArchiveClientCmd} =~ /\$archiveloc\b/ ) {
171                 $paramStr .= eval("qq{$Lang->{BackupPC_Archive2_location}}");
172             }
173             if ( $Conf{ArchiveClientCmd} =~ /\$compression\b/ ) {
174                 $paramStr .= eval("qq{$Lang->{BackupPC_Archive2_compression}}");
175             }
176             if ( $Conf{ArchiveClientCmd} =~ /\$parfile\b/
177                     && -x $Conf{ParPath} ) {
178                 $paramStr .= eval("qq{$Lang->{BackupPC_Archive2_parity}}");
179             }
180             if ( $Conf{ArchiveClientCmd} =~ /\$splitsize\b/
181                     && -x $Conf{SplitPath} ) {
182                 $paramStr .= eval("qq{$Lang->{BackupPC_Archive2_split}}");
183             }
184             my $content = eval("qq{$Lang->{BackupPC_Archive2}}");
185             Header(eval("qq{$Lang->{BackupPC__Archive}}"), $content, 1);
186             Trailer();
187         } elsif ( $In{type} == 2 ) {
188             my $reqFileName;
189             my $archivehost = $1 if ( $In{archivehost} =~ /(.+)/ );
190             for ( my $i = 0 ; ; $i++ ) {
191                 $reqFileName = "archiveReq.$$.$i";
192                 last if ( !-f "$TopDir/pc/$archivehost/$reqFileName" );
193             }
194             my($compname, $compext);
195             if ( $In{compression} == 2 ) {          # bzip2 compression
196                 $compname = $Conf{Bzip2Path};
197                 $compext = '.bz2';
198             } elsif ( $In{compression} == 1 ) {     # gzip compression
199                 $compname = $Conf{GzipPath};
200                 $compext = '.gz';
201             } else { # No Compression
202                 $compname = $Conf{CatPath};
203                 $compext = '.raw';
204             }
205             my $fullsplitsize = $In{splitsize} . '000000';
206             my %ArchiveReq = (
207                 # parameters for the archive
208                 archiveloc  => $In{archive_device},
209                 archtype    => $In{archive_type},
210                 compression => $compname,
211                 compext     => $compext,
212                 parfile     => $In{par},
213                 splitsize   => $fullsplitsize,
214                 host        => $archivehost,
215
216                 # list of hosts to restore
217                 HostList    => \@HostList,
218                 BackupList  => \@BackupList,
219
220                 # other info
221                 user        => $User,
222                 reqTime     => time,
223             );
224             my($archive) = Data::Dumper->new(
225                             [  \%ArchiveReq],
226                             [qw(*ArchiveReq)]);
227             $archive->Indent(1);
228             my $openPath = "$TopDir/pc/$archivehost/$reqFileName";
229             if ( open(REQ, ">", $openPath) ) {
230                 binmode(REQ);
231                 print(REQ $archive->Dump);
232                 close(REQ);
233             } else {
234                 ErrorExit(eval("qq{$Lang->{Can_t_open_create__openPath}}"));
235             }
236             $reply = $bpc->ServerMesg("archive $User $archivehost $reqFileName");
237             $str = eval("qq{$Lang->{Archive_requested}}");
238
239             my $content = eval("qq{$Lang->{BackupPC_Archive_Reply_from_server}}");
240             Header(eval("qq{$Lang->{BackupPC__Archive}}"), $content, 1);
241             Trailer();
242         }
243     }
244 }
245
246 1;