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