root/trunk/mt-check.cgi

Revision 4155, 19.6 kB (checked in by fumiakiy, 3 months ago)

Merged slapshot to trunk. "svn merge -r3786:4152 http://code.sixapart.com/svn/movabletype/branches/slapshot/ ."

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1#!/usr/bin/perl -w
2
3# Movable Type (r) Open Source (C) 2001-2009 Six Apart, Ltd.
4# This program is distributed under the terms of the
5# GNU General Public License, version 2.
6#
7# $Id$
8
9use strict;
10sub BEGIN {
11    my $dir;
12    if (eval { require File::Spec; 1; }) {
13        if (!($dir = $ENV{MT_HOME})) {
14            if ($0 =~ m!(.*[/\\])!) {
15                $dir = $1;
16            } else {
17                $dir = './';
18            }
19            $ENV{MT_HOME} = $dir;
20        }
21        unshift @INC, File::Spec->catdir($dir, 'lib');
22        unshift @INC, File::Spec->catdir($dir, 'extlib');
23    }
24}
25
26my $cfg_exist;
27my $mt_static_path = q();
28my $mt_cgi_path;
29if ((-f File::Spec->catfile($ENV{MT_HOME}, 'mt-config.cgi')) ||
30    (-f File::Spec->catfile($ENV{MT_HOME}, 'mt.cfg'))) {
31    $cfg_exist = 1;
32    my $file_handle = open(CFG, $ENV{MT_HOME}.'/mt.cfg') || open(CFG, $ENV{MT_HOME}.'/mt-config.cgi');
33    my $line;
34    while ($line = <CFG>) {
35        next if $line !~ /\S/ || $line =~ /^#/;
36        if ($line =~ s/StaticWebPath[\s]*([^\n]*)/$1/) {
37            $mt_static_path = $line;
38            chomp($mt_static_path);
39        }
40        elsif ($line =~ s/CGIPath[\s]*([^\n]*)/$1/) {
41            $mt_cgi_path = $line;
42            chomp($mt_cgi_path);
43        }
44    }
45    if ( !$mt_static_path && $mt_cgi_path ) {
46        $mt_cgi_path .= '/' if $mt_cgi_path !~ m|/$|;
47        $mt_static_path = $mt_cgi_path . 'mt-static/';
48    }
49}
50
51local $| = 1;
52
53use CGI;
54my $cgi = new CGI;
55my $view = $cgi->param("view");
56my $version = $cgi->param("version");
57# $version ||= '__PRODUCT_VERSION_ID__';
58
59my ($mt, $LH);
60my $lang = $cgi->param("language") || $cgi->param("__lang");
61eval {
62    require MT::App::Wizard;
63    $mt = MT::App::Wizard->new();
64   
65    require MT::Util;
66    $lang ||= MT::Util::browser_language();
67    my $cfg = $mt->config;
68    $cfg->PublishCharset('utf-8');
69    $cfg->DefaultLanguage($lang);
70    require MT::L10N;
71    if ( $mt ) {
72        $LH = $mt->language_handle;
73        $mt->set_language($lang);
74    }
75    else {
76        MT::L10N->get_handle($lang);
77    }
78};
79
80sub trans_templ {
81    my($text) = @_;
82    return $mt->translate_templatized($text) if $mt;
83    $text =~ s!(<MT_TRANS(?:\s+((?:\w+)\s*=\s*(["'])(?:<[^>]+?>|[^\3]+?)+?\3))+?\s*/?>)!
84        my($msg, %args) = ($1);
85        #print $msg;
86        while ($msg =~ /\b(\w+)\s*=\s*(["'])((?:<[^>]+?>|[^\2])*?)\2/g) {  #"
87            $args{$1} = $3;
88        }
89        $args{params} = '' unless defined $args{params};
90        my @p = map decode_html($_),
91                split /\s*%%\s*/, $args{params};
92        @p = ('') unless @p;
93        my $translation = translate($args{phrase}, @p);
94        $translation =~ s/([\\'])/\\$1/sg if $args{escape};
95        $translation;
96    !ge;
97    $text;
98}
99
100sub translate {
101    return (
102        $mt ? $mt->translate(@_)
103            : $LH ? $LH->maketext(@_)
104                  : merge_params(@_)
105    );
106}
107
108sub decode_html {
109    my($html) = @_;
110    if ($cfg_exist && (eval 'use MT::Util; 1')) {
111        return MT::Util::decode_html($html);
112    } else {
113        $html =~ s#&quot;#"#g;
114        $html =~ s#&lt;#<#g;
115        $html =~ s#&gt;#>#g;
116        $html =~ s#&amp;#&#g;
117    }
118    $html;
119}
120
121sub merge_params {
122    my ($msg, @param) = @_;
123    my $cnt = 1;
124    foreach my $p (@param) {
125        $msg =~ s/\[_$cnt\]/$p/g;
126        $cnt++;
127    }
128    $msg;
129}
130
131print "Content-Type: text/html; charset=utf-8\n\n";
132if (!$view) {
133    print trans_templ(<<HTML);
134
135<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
136<html xmlns="http://www.w3.org/1999/xhtml">
137
138<head>
139    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
140    <meta http-equiv="content-language" content="$lang" />
141   
142    <title><MT_TRANS phrase="Movable Type System Check"> [mt-check.cgi]</title>
143   
144    <style type=\"text/css\">
145        <!--
146       
147            body {
148                font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
149                font-size: 13px;
150                margin: 0;
151                padding: 0;
152                background-color: #fff;
153            }
154           
155            body.has-static {
156                background: #fff url('$mt_static_path/images/chromeless/chromeless_top_bg.gif') repeat-x;
157            }
158           
159            body.has-static #header {
160                background: url('$mt_static_path/images/chromeless/movable-type-logo.gif') no-repeat 25px 15px;
161                height: 55px;
162            }
163           
164            #content {
165                margin: 20px 20px 100px;
166            }
167           
168            h1 {
169                margin: 0;
170                padding: 10px;
171                text-align: center;
172                font-size: 22px;
173                color: #fff;
174                background: #000;
175            }
176            body.has-static #header h1 {
177                display: none;
178            }
179           
180            h2 {
181                margin-top: 2em;
182                margin-bottom: .5em;
183                font-size: 24px;
184                font-weight: normal;
185            }
186            h2#system-info {
187                margin-top: 1em;
188            }
189           
190            h3 {
191                color: #333;
192                font-size: 16px;
193                margin-bottom: 0px;
194            }
195   
196            p, ul {
197                margin: 0 0 .75em 0;
198                padding: 0;
199            }
200           
201            ul {
202                padding-left: 20px;
203            }
204           
205            .msg {
206                margin: 0 0 10px 0;
207                padding: 16px 10px 16px 46px;
208                background-repeat: no-repeat;
209            }
210            .msg-info {
211                background-color: #eaf2ff;
212                background-image: url('$mt_static_path/images/icon_info.gif');
213                background-position: 12px center;
214                border: 1px solid #999;
215            }
216
217                        .ready {
218                                color: #fff;
219                                background-color: #9C6;
220                border: 0;
221                padding-left: 5px;
222                        }
223
224            .msg-success {
225                background-color: #CFC;
226                background-image: url('$mt_static_path/images/icon_success.png');
227                background-position: 12px .75em;
228                font-size: 24px;
229            }
230            .msg-success h2 {
231                margin-top: 0;
232            }
233            .msg-success p {
234                font-size: 13px;
235            }
236
237            .info {
238                margin-left: 60px;
239                margin-right: 60px;
240                padding: 20px;
241                border: 1px solid #eaf2ff;
242                background: #eaf2ff;
243                color: #000;
244            }
245
246            .installed {
247                color: #93b06b;
248                padding-top: 0px;
249                margin-top: 0px;
250            }
251
252            .warning {
253                padding-top: 0px;
254                margin-top: 4px;
255                border-left: 1px solid red;
256                padding-left: 10px;
257                margin-left: 20px;
258            }
259           
260            ul.version {
261                margin-bottom: 0;
262            }
263       
264        //-->
265    </style>
266
267</head>
268
269HTML
270    if ($mt_static_path) {
271        print "<body class=\"has-static\">\n";
272    } else {
273        print "<body>\n";
274    }
275    print trans_templ(<<HTML);
276<div id="header"><h1><MT_TRANS phrase="Movable Type System Check"> [mt-check.cgi]</h1></div>
277
278<div id="content">
279<p class="msg msg-info"><MT_TRANS phrase="The mt-check.cgi script provides you with information on your system's configuration and determines whether you have all of the components you need to run Movable Type."></p>
280HTML
281}
282
283my $is_good = 1;
284my (@REQ, @DATA, @OPT);
285
286my @CORE_REQ = (
287    [ 'CGI', 0, 1, translate('CGI is required for all Movable Type application functionality.') ],
288
289    [ 'Image::Size', 0, 1, translate('Image::Size is required for file uploads (to determine the size of uploaded images in many different formats).') ],
290
291    [ 'File::Spec', 0.8, 1, translate('File::Spec is required for path manipulation across operating systems.') ],
292
293    [ 'CGI::Cookie', 0, 1, translate('CGI::Cookie is required for cookie authentication.') ],
294);
295
296my @CORE_DATA = (
297    [ 'DBI', 1.21, 0, translate('DBI is required to store data in database.') ],
298
299    [ 'DBD::mysql', 0, 0, translate('DBI and DBD::mysql are required if you want to use the MySQL database backend.') ],
300
301    [ 'DBD::Pg', 1.32, 0, translate('DBI and DBD::Pg are required if you want to use the PostgreSQL database backend.') ],
302
303    [ 'DBD::SQLite', 0, 0, translate('DBI and DBD::SQLite are required if you want to use the SQLite database backend.') ],
304
305    [ 'DBD::SQLite2', 0, 0, translate('DBI and DBD::SQLite2 are required if you want to use the SQLite 2.x database backend.') ],
306
307);
308
309my @CORE_OPT = (
310    [ 'HTML::Entities', 0, 0, translate('HTML::Entities is needed to encode some characters, but this feature can be turned off using the NoHTMLEntities option in the configuration file.') ],
311
312    [ 'LWP::UserAgent', 0, 0, translate('LWP::UserAgent is optional; It is needed if you wish to use the TrackBack system, the weblogs.com ping, or the MT Recently Updated ping.') ],
313
314    [ 'HTML::Parser', 0, 0, translate('HTML::Parser is optional; It is needed if you wish to use the TrackBack system, the weblogs.com ping, or the MT Recently Updated ping.') ],
315
316    [ 'SOAP::Lite', 0.50, 0, translate('SOAP::Lite is optional; It is needed if you wish to use the MT XML-RPC server implementation.') ],
317
318    [ 'File::Temp', 0, 0, translate('File::Temp is optional; It is needed if you would like to be able to overwrite existing files when you upload.') ],
319
320    [ 'Scalar::Util', 0, 1, translate('Scalar::Util is optional; It is needed if you want to use the Publish Queue feature.')],
321
322    [ 'List::Util', 0, 1, translate('List::Util is optional; It is needed if you want to use the Publish Queue feature.')],
323
324    [ 'Image::Magick', 0, 0, translate('Image::Magick is optional; It is needed if you would like to be able to create thumbnails of uploaded images.') ],
325
326    [ 'GD', 0, 0, translate('This module is needed if you would like to be able to create thumbnails of uploaded images.')],
327    [ 'IPC::Run', 0, 0, translate('This module is needed if you would like to be able to use NetPBM as the image driver for MT.')],
328
329    [ 'Storable', 0, 0, translate('Storable is optional; it is required by certain MT plugins available from third parties.')],
330
331    [ 'Crypt::DSA', 0, 0, translate('Crypt::DSA is optional; if it is installed, comment registration sign-ins will be accelerated.')],
332
333    [ 'Crypt::SSLeay', 0, 0, translate('This module and its dependencies are required in order to allow commenters to be authenticated by OpenID providers such as AOL and Yahoo! which require SSL support.')],
334
335    [ 'MIME::Base64', 0, 0, translate('MIME::Base64 is required in order to enable comment registration.')],
336
337    [ 'XML::Atom', 0, 0, translate('XML::Atom is required in order to use the Atom API.')],
338
339    [ 'Cache::Memcached', 0, 0, translate('Cache::Memcached and memcached server/daemon is required in order to use memcached as caching mechanism used by Movable Type.')],
340
341    [ 'Archive::Tar', 0, 0, translate('Archive::Tar is required in order to archive files in backup/restore operation.')],
342
343    [ 'IO::Compress::Gzip', 0, 0, translate('IO::Compress::Gzip is required in order to compress files in backup/restore operation.')],
344       
345    [ 'IO::Uncompress::Gunzip', 0, 0, translate('IO::Uncompress::Gunzip is required in order to decompress files in backup/restore operation.')],
346   
347    [ 'Archive::Zip', 0, 0, translate('Archive::Zip is required in order to archive files in backup/restore operation.')],
348
349    [ 'XML::SAX', 0, 0, translate('XML::SAX and/or its dependencies is required in order to restore.')],
350
351    [ 'Digest::SHA1', 0, 0, translate('Digest::SHA1 and its dependencies are required in order to allow commenters to be authenticated by OpenID providers including Vox and LiveJournal.')],
352    [ 'Mail::Sendmail', 0, 0, translate('Mail::Sendmail is required for sending mail via SMTP Server.')],
353    [ 'Safe', 0, 0, translate('This module is used in test attribute of MTIf conditional tag.')],
354    [ 'Digest::MD5', 0, 0, translate('This module is used by the Markdown text filter.')],
355    [ 'Text::Balanced', 0, 0, translate('This module is required in mt-search.cgi if you are running Movable Type on Perl older than Perl 5.8.') ],
356    [ 'XML::Parser', 0, 0, translate('This module required for action streams.')],
357);
358
359use Cwd;
360my $cwd = '';
361{
362    my($bad);
363    local $SIG{__WARN__} = sub { $bad++ };
364    eval { $cwd = Cwd::getcwd() };
365    if ($bad || $@) {
366        eval { $cwd = Cwd::cwd() };
367        if ($@ && $@ !~ /Insecure \$ENV{PATH}/) {
368            die $@;
369        }
370    }
371}
372
373my $ver = ref($^V) eq 'version' ? $^V->normal : ( $^V ? join('.', unpack 'C*', $^V) : $] );
374my $perl_ver_check = '';
375if ($] < 5.006001) {  # our minimal requirement for support
376    $perl_ver_check = <<EOT;
377<p class="warning"><MT_TRANS phrase="The version of Perl installed on your server ([_1]) is lower than the minimum supported version ([_2]). Please upgrade to at least Perl [_2]." params="$ver%%5.6.1"></p>
378EOT
379}
380my $config_check = '';
381if (!$cfg_exist) {
382    $config_check = <<CONFIG;
383<p class="warning"><MT_TRANS phrase="Movable Type configuration file was not found."></p>
384CONFIG
385}
386my $server = $ENV{SERVER_SOFTWARE};
387my $inc_path = join "<br />\n", @INC;
388print trans_templ(<<INFO);
389<h2 id="system-info"><MT_TRANS phrase="System Information"></h2>
390$perl_ver_check
391$config_check
392INFO
393if ($version) {
394    # sanitize down to letters numbers dashes and period
395    $version =~ s/[^a-zA-Z0-9\-\.]//g;
396print trans_templ(<<INFO);
397<ul class="version">
398    <li><strong><MT_TRANS phrase="Movable Type version:"></strong> <code>$version</code></li>
399</ul>
400INFO
401}
402print trans_templ(<<INFO);
403<ul>
404        <li><strong><MT_TRANS phrase="Current working directory:"></strong> <code>$cwd</code></li>
405        <li><strong><MT_TRANS phrase="MT home directory:"></strong> <code>$ENV{MT_HOME}</code></li>
406        <li><strong><MT_TRANS phrase="Operating system:"></strong> $^O</li>
407        <li><strong><MT_TRANS phrase="Perl version:"></strong> <code>$ver</code></li>
408        <li><strong><MT_TRANS phrase="Perl include path:"></strong><br /> <code>$inc_path</code></li>
409INFO
410if ($server) {
411print trans_templ(<<INFO);
412    <li><strong><MT_TRANS phrase="Web server:"></strong> <code>$server</code></li>
413INFO
414}
415
416## Try to create a new file in the current working directory. This
417## isn't a perfect test for running under cgiwrap/suexec, but it
418## is a pretty good test.
419my $TMP = "test$$.tmp";
420local *FH;
421if (open(FH, ">$TMP")) {
422    close FH;
423    unlink($TMP);
424    print trans_templ('    <li><MT_TRANS phrase="(Probably) Running under cgiwrap or suexec"></li>' . "\n");
425}
426
427print "\n\n</ul>\n";
428
429exit if $ENV{QUERY_STRING} && $ENV{QUERY_STRING} eq 'sys-check';
430
431if ($mt) {
432    my $req = $mt->registry("required_packages");
433    foreach my $key (keys %$req) {
434        next if $key eq 'DBI';
435        my $pkg = $req->{$key};
436        push @REQ, [ $key, $pkg->{version} || 0, 1, $pkg->{label}, $key, $pkg->{link} ];
437    }
438    my $drivers = $mt->object_drivers;
439    foreach my $key (keys %$drivers) {
440        my $driver = $drivers->{$key};
441        my $label = $driver->{label};
442        my $link = 'http://search.cpan.org/dist/' . $driver->{dbd_package};
443        $link =~ s/::/-/g;
444        push @DATA, [ $driver->{dbd_package}, $driver->{dbd_version}, 0,
445            $mt->translate("The [_1] database driver is required to use [_2].", $driver->{dbd_package}, $label),
446            $label, $link ];
447    }
448    unshift @DATA, [ 'DBI', 1.21, 0, translate('DBI is required to store data in database.') ]
449        if @DATA;
450    my $opt = $mt->registry("optional_packages");
451    foreach my $key (keys %$opt) {
452        my $pkg = $opt->{$key};
453        push @OPT, [ $key, $pkg->{version} || 0, 0, $pkg->{label}, $key, $pkg->{link} ];
454    }
455}
456@REQ  = @CORE_REQ  unless @REQ;
457@DATA = @CORE_DATA unless @DATA;
458@OPT  = @CORE_OPT  unless @OPT;
459
460for my $list (\@REQ, \@DATA, \@OPT) {
461    my $data = ($list == \@DATA);
462    my $req = ($list == \@REQ);
463    my $type;
464    my $phrase;
465
466    if (!$view) {
467        $phrase = translate("Checking for");
468    } else {
469        $phrase = translate("Installed");
470    }
471
472    if ($data) {
473        $type = translate("Data Storage");
474    } elsif ($req) {
475        $type = translate("Required");
476    } else {
477        $type = translate("Optional");
478    }
479    print trans_templ(qq{<h2><MT_TRANS phrase="[_1] [_2] Modules" params="$phrase%%$type"></h2>\n\t<div>\n});
480    if (!$req && !$data) {
481        if (!$view) {
482        print trans_templ(<<MSG);
483    <p class="msg msg-info"><MT_TRANS phrase="The following modules are <strong>optional</strong>. If your server does not have these modules installed, you only need to install them if you require the functionality that the module provides."></p>
484
485MSG
486       }
487    }
488    if ($data) {
489        if (!$view) {
490        print trans_templ(<<MSG);
491        <p class="msg msg-info"><MT_TRANS phrase="Some of the following modules are required by the various data storage options in Movable Type. In order run the system, your server needs to have DBI and at least one of the other modules installed."></p>
492
493MSG
494        }
495    }
496    my $got_one_data = 0;
497    my $dbi_is_okay = 0;
498    for my $ref (@$list) {
499        my($mod, $ver, $req, $desc) = @$ref;
500        if ('CODE' eq ref($desc)) {
501            $desc = $desc->();
502        }
503        print "<blockquote>\n" if $mod =~ m/^DBD::/;
504        print "    <h3>$mod" .
505            ($ver ? " (version &gt;= $ver)" : "") . "</h3>";
506        eval("use $mod" . ($ver ? " $ver;" : ";"));
507        if ($@) {
508            $is_good = 0 if $req;
509            my $msg = $ver ?
510                      trans_templ(qq{<p class="warning"><MT_TRANS phrase="Either your server does not have [_1] installed, the version that is installed is too old, or [_1] requires another module that is not installed." params="$mod"> }) :
511                      trans_templ(qq{<p class="warning"><MT_TRANS phrase="Your server does not have [_1] installed, or [_1] requires another module that is not installed." params="$mod"> });
512            $msg   .= $desc .
513                      trans_templ(qq{ <MT_TRANS phrase="Please consult the installation instructions for help in installing [_1]." params="$mod"></p>\n\n});
514            print $msg . "\n\n";
515        } else {
516            if ($data) {
517                $dbi_is_okay = 1 if $mod eq 'DBI';
518                if ($mod eq 'DBD::mysql') {
519                    if ($DBD::mysql::VERSION == 3.0000) {
520                        print trans_templ(qq{<p class="warning"><MT_TRANS phrase="The DBD::mysql version you have installed is known to be incompatible with Movable Type. Please install the current release available from CPAN."></p>});
521                    }
522                }
523                if (!$dbi_is_okay) {
524                    print trans_templ(qq{<p class="warning"><MT_TRANS phrase="The $mod is installed properly, but requires an updated DBI module. Please see note above regarding the DBI module requirements."></p>});
525                } else {
526                    $got_one_data = 1 if $mod ne 'DBI';
527                }
528            }
529            print trans_templ(qq{<p class="installed"><MT_TRANS phrase="Your server has [_1] installed (version [_2])." params="$mod%%} . $mod->VERSION . qq{"></p>\n\n});
530        }
531        print "</blockquote>\n" if $mod =~ m/^DBD::/;
532    }
533    $is_good &= $got_one_data if $data;
534    print "\n\t</div>\n\n";
535}
536
537if ($is_good && $cfg_exist) {
538    if (!$view) {
539    print trans_templ(<<HTML);
540   
541    <div class="msg msg-success">
542        <h2><MT_TRANS phrase="Movable Type System Check Successful"></h2>
543        <p><strong><MT_TRANS phrase="You're ready to go!"></strong> <MT_TRANS phrase="Your server has all of the required modules installed; you do not need to perform any additional module installations. Continue with the installation instructions."></p>
544    </div>
545
546</div>
547
548HTML
549    }
550}
551
552print "</body>\n\n</html>\n";
Note: See TracBrowser for help on using the browser.