4b3a372deb91555594f97865b11c1e0718edec4a
[BackupPC.git] / lib / BackupPC / CGI / RestoreFile.pm
1 #============================================================= -*-perl-*-
2 #
3 # BackupPC::CGI::RestoreFile package
4 #
5 # DESCRIPTION
6 #
7 #   This module implements the RestoreFile 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 3.0.0beta2, released 11 Nov 2006.
32 #
33 # See http://backuppc.sourceforge.net.
34 #
35 #========================================================================
36
37 package BackupPC::CGI::RestoreFile;
38
39 use strict;
40 use Encode;
41 use BackupPC::CGI::Lib qw(:all);
42 use BackupPC::FileZIO;
43 use BackupPC::Attrib qw(:all);
44 use BackupPC::View;
45
46
47 sub action
48 {
49     restoreFile($In{host}, $In{num}, $In{share}, $In{dir});
50 }
51
52 sub restoreFile
53 {
54     my($host, $num, $share, $dir, $skipHardLink, $origName) = @_;
55     my($Privileged) = CheckPermission($host);
56
57     #
58     # Some common content (media) types from www.iana.org (via MIME::Types).
59     #
60     my $Ext2ContentType = {
61         'asc'  => 'text/plain',
62         'avi'  => 'video/x-msvideo',
63         'bmp'  => 'image/bmp',
64         'book' => 'application/x-maker',
65         'cc'   => 'text/plain',
66         'cpp'  => 'text/plain',
67         'csh'  => 'application/x-csh',
68         'csv'  => 'text/comma-separated-values',
69         'c'    => 'text/plain',
70         'deb'  => 'application/x-debian-package',
71         'doc'  => 'application/msword',
72         'dot'  => 'application/msword',
73         'dtd'  => 'text/xml',
74         'dvi'  => 'application/x-dvi',
75         'eps'  => 'application/postscript',
76         'fb'   => 'application/x-maker',
77         'fbdoc'=> 'application/x-maker',
78         'fm'   => 'application/x-maker',
79         'frame'=> 'application/x-maker',
80         'frm'  => 'application/x-maker',
81         'gif'  => 'image/gif',
82         'gtar' => 'application/x-gtar',
83         'gz'   => 'application/x-gzip',
84         'hh'   => 'text/plain',
85         'hpp'  => 'text/plain',
86         'h'    => 'text/plain',
87         'html' => 'text/html',
88         'htmlx'=> 'text/html',
89         'htm'  => 'text/html',
90         'iges' => 'model/iges',
91         'igs'  => 'model/iges',
92         'jpeg' => 'image/jpeg',
93         'jpe'  => 'image/jpeg',
94         'jpg'  => 'image/jpeg',
95         'js'   => 'application/x-javascript',
96         'latex'=> 'application/x-latex',
97         'maker'=> 'application/x-maker',
98         'mid'  => 'audio/midi',
99         'midi' => 'audio/midi',
100         'movie'=> 'video/x-sgi-movie',
101         'mov'  => 'video/quicktime',
102         'mp2'  => 'audio/mpeg',
103         'mp3'  => 'audio/mpeg',
104         'mpeg' => 'video/mpeg',
105         'mpg'  => 'video/mpeg',
106         'mpp'  => 'application/vnd.ms-project',
107         'pdf'  => 'application/pdf',
108         'pgp'  => 'application/pgp-signature',
109         'php'  => 'application/x-httpd-php',
110         'pht'  => 'application/x-httpd-php',
111         'phtml'=> 'application/x-httpd-php',
112         'png'  => 'image/png',
113         'ppm'  => 'image/x-portable-pixmap',
114         'ppt'  => 'application/powerpoint',
115         'ppt'  => 'application/vnd.ms-powerpoint',
116         'ps'   => 'application/postscript',
117         'qt'   => 'video/quicktime',
118         'rgb'  => 'image/x-rgb',
119         'rtf'  => 'application/rtf',
120         'rtf'  => 'text/rtf',
121         'shar' => 'application/x-shar',
122         'shtml'=> 'text/html',
123         'swf'  => 'application/x-shockwave-flash',
124         'tex'  => 'application/x-tex',
125         'texi' => 'application/x-texinfo',
126         'texinfo'=> 'application/x-texinfo',
127         'tgz'  => 'application/x-gtar',
128         'tiff' => 'image/tiff',
129         'tif'  => 'image/tiff',
130         'txt'  => 'text/plain',
131         'vcf'  => 'text/x-vCard',
132         'vrml' => 'model/vrml',
133         'wav'  => 'audio/x-wav',
134         'wmls' => 'text/vnd.wap.wmlscript',
135         'wml'  => 'text/vnd.wap.wml',
136         'wrl'  => 'model/vrml',
137         'xls'  => 'application/vnd.ms-excel',
138         'xml'  => 'text/xml',
139         'xwd'  => 'image/x-xwindowdump',
140         'z'    => 'application/x-compress',
141         'zip'  => 'application/zip',
142         %{$Conf{CgiExt2ContentType}},       # add site-specific values
143     };
144     if ( !$Privileged ) {
145         ErrorExit(eval("qq{$Lang->{Only_privileged_users_can_restore_backup_files2}}"));
146     }
147     ServerConnect();
148     ErrorExit($Lang->{Empty_host_name}) if ( $host eq "" );
149
150     $dir = "/" if ( $dir eq "" );
151     my @Backups = $bpc->BackupInfoRead($host);
152     my $view = BackupPC::View->new($bpc, $host, \@Backups);
153     my $a = $view->fileAttrib($num, $share, $dir);
154     if ( $dir =~ m{(^|/)\.\.(/|$)} || !defined($a) ) {
155         $dir = decode_utf8($dir);
156         ErrorExit("Can't restore bad file ${EscHTML($dir)} ($num, $share)");
157     }
158     my $f = BackupPC::FileZIO->open($a->{fullPath}, 0, $a->{compress});
159     my $data;
160     if ( !$skipHardLink && $a->{type} == BPC_FTYPE_HARDLINK ) {
161         #
162         # hardlinks should look like the file they point to
163         #
164         my $linkName;
165         while ( $f->read(\$data, 65536) > 0 ) {
166             $linkName .= $data;
167         }
168         $f->close;
169         $linkName =~ s/^\.\///;
170         restoreFile($host, $num, $share, $linkName, 1, $dir);
171         return;
172     }
173     $bpc->ServerMesg("log User $User recovered file $host/$num:$share/$dir ($a->{fullPath})");
174     $dir = $origName if ( defined($origName) );
175     my $ext = $1 if ( $dir =~ /\.([^\/\.]+)$/ );
176     my $contentType = $Ext2ContentType->{lc($ext)}
177                                     || "application/octet-stream";
178     my $fileName = $1 if ( $dir =~ /.*\/(.*)/ );
179     $fileName =~ s/"/\\"/g;
180     print "Content-Type: $contentType\n";
181     print "Content-Transfer-Encoding: binary\n";
182     print "Content-Disposition: attachment; filename=\"$fileName\"\n\n";
183     while ( $f->read(\$data, 1024 * 1024) > 0 ) {
184         print STDOUT $data;
185     }
186     $f->close;
187 }
188
189 1;