#!/bin/sh
eval 'if [ -x /usr/local/cpanel/3rdparty/bin/perl ]; then exec /usr/local/cpanel/3rdparty/bin/perl -x -- $0 ${1+"$@"}; else exec /usr/bin/perl -x $0 ${1+"$@"}; fi;'
  if 0;

#!/usr/bin/perl
#
# cpanel - cpanel-install                         Copyright(c) 2013 cPanel, Inc.
#                                                           All rights Reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
#
#
# Zend Guard/Optimizer installer

use strict;
use warnings;
use File::Path ();
use lib '/usr/local/cpanel';
use Cpanel::FileUtils   ();
use Cpanel::SafeFile    ();
use Cpanel::SafeRun     ();
use Cpanel::SafeDir::MK ();    # safemkdir

# Base directory where the Zend Opt is installed into
my $INSTALL_DIR = q{/usr/local/Zend/lib};

# Relates PHP version to Zend Opt versions
my %Zend = (
    '5.2' => {
        zend_version => q{3.3.9},                              # zend opt version number
        zend_dir     => q{Optimizer-3.3.9/php-5.2.x},          # sub directory of $INSTALL_DIR
        zend_file    => q{ZendOptimizer.so},                   # name of the actual extension
        src_path     => 'data/5_2_x_comp/ZendOptimizer.so',    # sub directory in optmod tarball
    },
    '5.3' => {
        zend_version => q{5.5},
        zend_dir     => q{Guard-5.5.0/php-5.3.x},
        zend_file    => q{ZendGuardLoader.so},
        src_path     => 'data/5_3_x_comp/ZendGuardLoader.so',
    },
    '5.4' => {
        zend_version => q{6.0},
        zend_dir     => q{Guard-6.0.0/php-5.4.x},
        zend_file    => q{ZendGuardLoader.so},
        src_path     => 'data/5_4_x_comp/ZendGuardLoader.so',
    },
    '5.5' => {
        zend_version => q{7.0},
        zend_dir     => q{Guard-7.0.0/php-5.5.x},
        zend_file    => q{ZendGuardLoader.so},
        src_path     => 'data/5_5_x_comp/ZendGuardLoader.so',
    },
    '5.6' => {
        zend_version => q{7.0},
        zend_dir     => q{Guard-7.0.0/php-5.6.x},
        zend_file    => q{ZendGuardLoader.so},
        src_path     => 'data/5_6_x_comp/ZendGuardLoader.so',
    },
);

# Given a prefix, return the corresponding path to php.ini
sub php_ini {
    my $prefix = shift;
    my $ini;

    $prefix =~ s/\/$//;

    if ( $prefix eq '/usr/local/cpanel/3rdparty' || $prefix eq '/var/cpanel/3rdparty' ) {
        $ini = q{/usr/local/cpanel/3rdparty/etc/php.ini};
    }
    else {
        $ini = qq{$prefix/lib/php.ini};
    }

    return $ini;
}

# Gathers a list of valid PHP installations
sub is_valid_prefix {
    my $prefix  = shift;
    my $php_ini = php_ini($prefix);

    unless ( -e $php_ini ) {
        print "Skipping install to $prefix, missing php.ini\n";
        return 0;
    }
    unless ( -e $prefix . '/bin/php' ) {
        print "Skipping install to $prefix, missing php\n";
        return 0;
    }
    unless ( -e $prefix . '/bin/phpize' ) {
        print "Skipping install to $prefix, missing phpize\n";
        return 0;
    }
    unless ( -e $prefix . '/bin/php-config' ) {
        print "Skipping install to $prefix, missing php-config\n";
        return 0;
    }

    return 1;
}

# Determines the PHP version
sub php_version {
    my $prefix = shift;
    my $version;
    my @cmd;

    print "Determining PHP version\n";

    if ( -e '/usr/local/cpanel/scripts/php.ini' ) {
        @cmd = ( $prefix . '/bin/php', '-c', '/usr/local/cpanel/scripts/php.ini', '-v' );
    }
    else {
        @cmd = ( $prefix . '/bin/php', '-v' );
    }

    my $phpout = Cpanel::SafeRun::saferunallerrors(@cmd);

    if ( $phpout =~ m/^PHP\s+(\d\.\d)\.\d+\S*\s+\(([^\)]+)\)/m ) {
        $version = $1;
    }
    else {
        print "Could not determine PHP version from output:\n";
        print $phpout;
    }

    return $version;
}

sub zend_info {
    my $php_version = shift;
    my $info        = $Zend{$php_version};

    unless ($info) {
        print "Unsupported version of PHP, $php_version\n";
    }

    return $info;
}

sub activate_zendopt {
    my $php_ini   = shift;
    my $zend_path = shift;

    # Zend Optimizer/Guard should be added to the end of the php.ini file
    my $lock = Cpanel::SafeFile::safeopen( \*INI, '+<', $php_ini );
    unless ($lock) {
        print "ERROR: Could not log $php_ini for read/write\n";
        return undef;
    }

    my @ini_contents = <INI>;
    seek( INI, 0, 0 );
    foreach my $line (@ini_contents) {
        next if ( $line =~ /^\s*zend_extension_manager\.optimizer(_ts)?\s*=\s*"?\S+\/Optimizer(_TS)?-[\d\.]+"?\s*$/i );
        next if ( $line =~ /^\s*zend_optimizer\.\S+.*$/i );
        next if ( $line =~ /^\s*zend_extension(_ts)?\s*=\s*"?\S+Zend(ExtensionManager|Optimizer|GuardLoader)(_TS)?\.so"?\s*$/i );
        print INI $line;
    }
    print INI "\n" unless ( $ini_contents[-1] =~ /\n$/ );
    print INI qq{zend_extension="$zend_path"\n};
    truncate( INI, tell(INI) );

    Cpanel::SafeFile::safeclose( \*INI, $lock );

    return 1;
}

sub install_zend {
    my @argv = @_;
    my @prefixes = grep { is_valid_prefix($_) } ( '/usr/local', '/usr/local/php4', @argv );
    my ( $php_version, $install_directory );
    my $installed = 0;

    foreach my $php_prefix (@prefixes) {
        my $php_ini = php_ini($php_prefix);
        $php_prefix =~ s/\/$//;

        # determine PHP version
        my $php_version = php_version($php_prefix);
        next unless $php_version;

        # determine correct version and path of Zend to use
        my $zend_info = zend_info($php_version);
        next unless $zend_info;

        # create installation directory where the Zend extension
        # will be installed
        my $install_dir = sprintf( '%s/%s', $INSTALL_DIR, $zend_info->{'zend_dir'} );
        next unless Cpanel::SafeDir::MK::safemkdir($install_dir);

        unless ( -e $zend_info->{'src_path'} ) {
            print "No Zend Guard Loader binaries available for this version of PHP!\n";
            next;
        }

        print "Installing Zend Guard/Optimizer $zend_info->{'zend_version'} for PHP $php_version\n";
        Cpanel::FileUtils::safecopy( $zend_info->{'src_path'}, $install_dir ) || die "Could not copy $zend_info->{src_path} to $install_dir: $!";

        next unless activate_zendopt( $php_ini, sprintf( '%s/%s', $install_dir, $zend_info->{'zend_file'} ) );
        print "Activated Zend Guard/Optimizer\n";

        $installed++;
    }

    return $installed;
}

exit( install_zend(@ARGV) ? 0 : 1 );

