File Coverage

blib/lib/WE_Frontend/Installer.pm
Criterion Covered Total %
statement 24 162 14.8
branch 0 64 0.0
condition 0 21 0.0
subroutine 8 21 38.1
pod 6 9 66.6
total 38 277 13.7


line stmt bran cond sub pod time code
1             # -*- perl -*-
2              
3             #
4             # $Id: Installer.pm,v 1.6 2004/06/10 13:18:02 eserte Exp $
5             # Author: Slaven Rezic
6             #
7             # Copyright (C) 2001 Online Office Berlin. All rights reserved.
8             # Copyright (C) 2002 Slaven Rezic.
9             # This is free software; you can redistribute it and/or modify it under the
10             # terms of the GNU General Public License, see the file COPYING.
11              
12             #
13             # Mail: slaven@rezic.de
14             # WWW: http://we-framework.sourceforge.net
15             #
16              
17             package WE_Frontend::Installer;
18              
19 2     2   1651 use strict;
  2         5  
  2         63  
20 2     2   9 use vars qw($VERSION $magicfile $magiccontent);
  2         3  
  2         167  
21             $VERSION = sprintf("%d.%02d", q$Revision: 1.6 $ =~ /(\d+)\.(\d+)/);
22              
23 2     2   12 use base qw(Class::Accessor);
  2         3  
  2         980  
24             __PACKAGE__->mk_accessors(qw(Main));
25              
26 2     2   23287 use CGI qw(:standard);
  2         35293  
  2         16  
27             #use CGI::Carp qw(fatalsToBrowser);
28 2     2   7863 use File::Path;
  2         6  
  2         162  
29 2     2   13 use File::Basename;
  2         4  
  2         161  
30 2     2   2129 use File::stat;
  2         16837  
  2         43  
31              
32 2     2   776 use WE::Util::Functions qw(_save_pwd);
  2         5  
  2         4539  
33              
34             $magicfile = "magic";
35             $magiccontent = "Elvis is alive";
36              
37             =head1 NAME
38              
39             WE_Frontend::Installer - handle servicepack creation and handling
40              
41             =head1 SYNOPSIS
42              
43             use WE_Frontend::Installer;
44             WE_Frontend::Installer->create_servicepack($tarfile);
45              
46             =head1 DESCRIPTION
47              
48             This module handles servicepack creation and handling.
49              
50             =head2 METHODS and FUNCTIONS
51              
52             =over 4
53              
54             =item new
55              
56             Return a new C object.
57              
58             =cut
59              
60             sub new {
61 0     0 1   bless {}, $_[0];
62             }
63              
64             =item objectify($self)
65              
66             Return a new C object, if it does not already
67             exist in C<$self>. Should be called as a static method.
68              
69             =cut
70              
71             sub objectify {
72 0     0 1   my $self = shift;
73 0 0 0       if (!$self || $self eq __PACKAGE__) {
74 0           require WE_Frontend::MainAny;
75 0           $self = new WE_Frontend::Installer;
76 0           my $main = WE_Frontend::MainAny->new;
77 0 0         if (!$main) {
78 0           die "Can't make \$main object";
79             }
80              
81 0           $self->Main($main);
82             }
83 0           $self;
84             }
85              
86 0     0 0   sub Config { shift->Main->Config(@_) }
87              
88             =item main
89              
90             Create a HTML page for uploading and installing a service pack. This
91             calls either upload_form or handle_tar.
92              
93             =cut
94              
95             sub main {
96 0     0 1   my $self = shift;
97 0           $self = objectify($self);
98              
99 0           print header, "";
100              
101 0           eval {
102 0 0         if (!param('tarfile')) {
103 0           $self->upload_form;
104             } else {
105 0           $self->handle_tar;
106             }
107             };
108 0 0         if ($@) {
109 0           print "Folgende Fehler sind aufgetreten:",
110             br,pre(escapeHTML($@)),p;
111             }
112              
113 0           print "
";
114 0           print '
';
115 0           print "zurück zum Site-Editor
";
116             }
117              
118             =item upload_form
119              
120             Create a HTML page for uploading a service pack.
121              
122             =cut
123              
124             sub upload_form {
125 0     0 1   my $self = shift;
126 0           my $scriptname = script_name();
127 0           print qq~
128            
133            
134             Servicepack-Datei:
135            
136            
137            

~;
138             }
139              
140             =item upload_form
141              
142             Create a HTML page for installing a previously uploaded service pack.
143              
144             =cut
145              
146             sub handle_tar {
147 0     0 0   my $self = shift;
148 0           require Archive::Tar;
149 0           my $uploadfile = param('tarfile');
150 0           my $tmpdir = tmpdir();
151 0 0         if (!defined $tmpdir) {
152 0           die "Cannot find suitable temporary directory";
153             }
154 0           my $extrdir = "$tmpdir/webeditor_service";
155 0 0         if (-d $extrdir) {
156 0           rmtree([$extrdir], 0, 1);
157             }
158 0           mkdir $extrdir, 0775;
159 0 0         if (!-d $extrdir) {
160 0           die "Cannot create extraction directory $extrdir";
161             }
162 0 0         chdir $extrdir or die "Can't chdir to $extrdir: $!";
163              
164 0           my $tarfilename = "$extrdir/service.tar.gz";
165 0 0         open(SP,">$tarfilename") or die "Can't writeopen $tarfilename: $!";
166 0           binmode SP;
167 0           while (<$uploadfile>) {
168 0           print SP $_;
169             }
170 0           close SP;
171 0           print "File-Upload abgeschlossen.
";
172              
173 0           my $tar = Archive::Tar->new();
174 0           $tar->read($tarfilename);
175              
176 0           my $is_servicepack = 0;
177 0           foreach my $m ($magicfile, "./$magicfile") {
178 0 0         if ($tar->get_content($m) =~ /\Q$magiccontent/) {
179 0           $is_servicepack++;
180 0           last;
181             }
182             }
183              
184 0 0         if ($is_servicepack) {
185             # XXX $tar->extract geht nicht?!
186 0 0         if (!$tar->extract_archive($tarfilename)) {
187 0           print "Extrahieren von $tarfilename fehlgeschlagen: ". $tar->error();
188 0           goto CLEANUP;
189             } else {
190 0           print "Dateien extrahiert.
\n";
191             };
192             } else {
193 0           print "Das scheint kein gültiges Servicepack zu sein!
";
194 0           goto CLEANUP;
195             }
196              
197 0           unlink "$extrdir/$magicfile";
198 0           $self->install($extrdir);
199              
200 0           CLEANUP:
201             unlink $tarfilename;
202             }
203              
204             =item install($dir)
205              
206             Install the contents of directory C<$dir> to the rootdir of the
207             system.
208              
209             =cut
210              
211             sub install {
212 0     0 1   my($self, $dir) = @_;
213              
214 0 0         if (-e "$dir/install.pl") {
215 0 0         if (-x "$dir/install.pl") {
216 0           system("$dir/install.pl");
217 0 0         if ($?/256!=0) {
218 0           print "Fehler beim Ausführen von install.pl!
\n";
219             }
220             } else {
221 0           print "install.pl ist nicht ausführbar.
\n";
222             }
223             } else {
224 0           print "Kopieren:\n
";
225 0           my(@f) = glob("$dir/*");
226 0           @f = grep { $_ !~ /\.tar\.gz$/ } @f; # tar.gz-Dateien ausschließen
  0            
227 0           my @cmd = ('cp', '-Rf', @f, $self->Config->paths->rootdir);
228 0           print join(" ",@cmd), "
";
229 0           system(@cmd);
230             }
231              
232 0           CLEANUP: 1;
233             # XXX missing cleanup of $dir
234             }
235              
236             sub tmpdir {
237 0     0 0   foreach my $d ("/tmp", "/var/tmp", "/usr/tmp", "/temp", "C:/temp", "C:/windows/temp", "D:/temp") {
238 0 0         next if !defined $d;
239 0 0 0       next if !-d $d || !-w $d;
240 0           return $d;
241             }
242 0           undef;
243             }
244              
245             =item WE_Frontend::Installer->create_servicepack($destfile, %args)
246              
247             =item $self->create_servicepack($destfile, %args)
248              
249             Create a service pack file. Ignores all WEsiteinfo*.pm files.
250              
251             The %args hash may contain the following key-value pairs:
252              
253             =over 4
254              
255             =item -wesiteinfo
256              
257             If -wesiteinfo is specified, then use this file as the WEsiteinfo.pm
258             file for the target site. Most times there is a WEsiteinfo.pm file for
259             local development and a WEsiteinfo_customer.pm file for the customer
260             site.
261              
262             =item -since date
263              
264             Only include files newer than C. L is used for
265             parsing the date string.
266              
267             =item -v
268              
269             Set to 1 to generate verbose messages.
270              
271             =back
272              
273             =cut
274              
275             sub create_servicepack {
276 0     0 1   my($self, $destfile, %args) = @_;
277              
278 0           $self = objectify($self);
279              
280 0 0         if (!defined $destfile) {
281 0           die "Destfile not given";
282             }
283              
284 0           my $since;
285 0 0         if (defined $args{-since}) {
286 0           require Date::Parse;
287 0           $since = Date::Parse::str2time($args{-since});
288 0 0         if (!defined $since) {
289 0           die "Could not parse the date $args{-since}";
290             }
291             }
292 0           my $v = $args{-verbose};
293              
294 0           require Archive::Tar;
295 0           require File::Find;
296              
297 0           require 5.006; # this perl includes a version of File::Find which can
298             # follow symlinks
299              
300 0           my $tar = new Archive::Tar;
301              
302             my $is_new = sub {
303 0     0     my $file = shift;
304 0   0       return (!defined $since || stat($file)->mtime > $since);
305 0           };
306              
307 0           my @files;
308             my $wanted = sub {
309 0 0 0 0     if (-d $_ && (/^(RCS|CVS|\.svn|headlines|photos)$/ ||
      0        
310             $File::Find::name =~ m;(we_data/content|html/.+);)) {
311 0           $File::Find::prune = 1;
312 0           return;
313             }
314 0 0 0       if (-f $_ && (/^(\.cvsignore|WEsiteinfo.*\.pm|.*~|\.\#.*)$/ ||
      0        
315             $File::Find::name =~ m;( we_data/.*\.db$ |
316             we_data/.*\.lock$
317             );x)
318             ) {
319 0           return;
320             }
321 0 0         if (-f $_) {
322 0 0         return if !$is_new->($_);
323 0           push @files, $File::Find::name;
324             }
325 0           };
326              
327 0           my $rootdir = $self->Config->paths->rootdir;
328 0           my $cgidir = $self->Config->paths->cgidir;
329             _save_pwd {
330 0 0   0     chdir $rootdir or die "Can't chdir to $rootdir: $!";
331              
332 0           File::Find::find({wanted => $wanted, follow => 1 }, ".");
333              
334             # Hmmm... add_files does not work?!
335             # But nevertheless I need resolved symbolic links, so this is the
336             # only possibility.
337 0           foreach my $f (@files) {
338 0 0         warn "Add $f ...\n" if $v;
339 0           _tar_add_file($tar, $f);
340             }
341 0           };
342              
343 0 0         if ($args{-wesiteinfo}) {
344 0           my $as = $cgidir;
345 0           $as =~ s|^$rootdir/*||;
346 0           $as .= "/WEsiteinfo.pm";
347 0 0         if ($is_new->($args{-wesiteinfo})) {
348 0 0         warn "Add $as ...\n" if $v;
349 0           _tar_add_file($tar, $args{-wesiteinfo}, $as);
350             }
351             }
352              
353 0           $tar->add_data($magicfile, $magiccontent);
354              
355 0 0         $tar->write($destfile, 9)
356             or die "Can't write to $destfile: " . $tar->error;
357              
358             }
359              
360             sub _tar_add_file {
361 0     0     my($tar, $f, $as) = @_;
362 0 0         open(F, $f) or die "Can't open file $f: $!";
363 0           local $/ = undef;
364 0           my $buf = ;
365 0           close F;
366 0 0         $as = $f if !defined $as;
367 0           my $s = stat $f;
368 0           my %stat = (mode => $s->mode,
369             mtime => $s->mtime);
370 0           $tar->add_data($as, $buf, \%stat);
371             }
372              
373             1;
374              
375             __END__