File: //proc/self/root/proc/self/root/scripts.20110531.215904.25158/installport.pl
#!/usr/bin/perl
# cpanel - installport.pl Copyright(c) 2010 cPanel, Inc.
# All rights Reserved.
# copyright@cpanel.net http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
BEGIN {
unshift @INC, '/scripts', '/usr/local/cpanel';
$ENV{'PATH'} .= ":/sbin:/usr/sbin:/usr/local/bin";
}
use strict;
use Cpanel::cPanelFunctions ();
use Cpanel::StringFunc ();
use Cpanel::Logger ();
use Cpanel::OSSys;
use Cpanel::SafeFile;
use cPanelRPM;
use IPC::Open3;
my $logger = Cpanel::Logger->new();
my ( $system, $release, $machine ) = ( Cpanel::OSSys::uname() )[ 0, 2, 4 ];
$| = 1;
sub postinstall {
my $pkg = shift;
return if !$pkg;
print "Running post install scripts for $pkg....";
Cpanel::cPanelFunctions::installcppkg( 'freebsd', $pkg );
print "Done\n";
}
sub installport {
my ( $virginpkg, $skipnew, $force ) = @_;
my ($pkg) = pkgmap($virginpkg);
if ( $pkg =~ /ghostscript/ ) {
print "No auto-install for ghostscript\n";
return;
}
open( PORTSIGN, "/etc/ports.ignore" );
while (<PORTSIGN>) {
s/\n//g;
next if !$_;
if ( $_ eq $virginpkg ) {
print "Skipping $_ (listed in /etc/ports.ignore)\n";
close(PORTSIGN);
return;
}
}
close(PORTSIGN);
my ($path);
if ( $pkg =~ m/exim/ && -d '/usr/ports/mail/exim' ) {
$path = '/usr/ports/mail/exim';
}
elsif ( $pkg eq 'compat3x' && -d '/usr/ports/misc/compat3x' ) {
$path = '/usr/ports/misc/compat3x';
}
elsif ( $pkg eq 'compat4x' && -d '/usr/ports/misc/compat4x' ) {
$path = '/usr/ports/misc/compat4x';
}
if ( !$path ) {
opendir( PORTS, '/usr/ports' );
my (@DIRS) = readdir(PORTS);
closedir(PORTS);
@DIRS = grep( !/^\./, @DIRS );
print "Searching ports for $pkg .";
foreach my $portdir (@DIRS) {
next if ( $portdir =~ /^dist/ );
next if ( $portdir eq 'japanese' && $ENV{'LANG'} !~ m/jp/ );
next if ( $portdir eq 'audio' && $pkg eq 'muse' );
print '.';
opendir( PORTS, "/usr/ports/${portdir}" );
my (@PDIRS) = readdir(PORTS);
closedir(PORTS);
@PDIRS = grep( !/^\./, @PDIRS );
foreach my $portnames (@PDIRS) {
if ( $portnames eq $pkg ) {
next unless -d "/usr/ports/${portdir}/${portnames}";
$path = "/usr/ports/${portdir}/${portnames}";
print "...found $pkg in $path...";
last;
}
}
last if $path;
}
print ".Done\n";
}
if ( !$path ) {
opendir( PORTS, '/usr/ports' );
my (@DIRS) = readdir(PORTS);
closedir(PORTS);
@DIRS = grep( !/^\./, @DIRS );
print "Regexp Searching ports for ${pkg}.";
foreach my $portdir (@DIRS) {
next if ( $portdir =~ /^dist/ );
next if ( $portdir eq 'japanese' && $ENV{'LANG'} !~ m/jp/ );
next if ( $portdir eq 'audio' && $pkg eq 'muse' );
print ".";
opendir( PORTS, "/usr/ports/${portdir}" );
my (@PDIRS) = readdir(PORTS);
closedir(PORTS);
@PDIRS = grep( !/^\./, @PDIRS );
foreach my $portnames (@PDIRS) {
if ( $portnames =~ /^\Q${pkg}\E/ ) {
next unless -d "/usr/ports/${portdir}/${portnames}";
$path = "/usr/ports/${portdir}/${portnames}";
print "...found $pkg in $path...";
last;
}
}
last if $path;
}
print ".Done\n";
}
if ( !$path ) {
print "Unable to upgrade $pkg\n";
return;
}
chdir '/usr/ports';
my $wants;
( $wants, $virginpkg ) = getportversion($path);
my @CV = split( /\n/, getpkginfo("${virginpkg}") );
@CV = grep( /^\Q${virginpkg}\E-(${machine}|\d+)/, @CV );
my $curv = $CV[$#CV];
( $curv, undef ) = split( /\s+/, $curv );
$curv =~ s/-${machine}$//g;
my $has = $curv;
$has =~ s/^\Q${virginpkg}\E//g;
$has =~ s/^-//g;
$has =~ s/\_([^\_]+)$/-$1/g;
$wants =~ s/\_([^\_]+)$/-$1/g;
$has =~ s/,/./g;
$wants =~ s/,/./g;
if ( !$force ) {
my $compareopt = cPanelRPM::compareversion( $wants, $has );
if ( $compareopt > 0 ) {
print "$pkg ($has) is newer then requested version $wants. (no install needed)\n";
return 0;
}
my $isupgrade = 0;
if ( $compareopt == 0 ) {
$isupgrade = 1;
print "$pkg ($has) is already installed.\n";
if ( $skipnew != 1 ) {
return 0;
}
}
}
if ( !chdir $path ) {
print "Unable to chdir to $path: $!\n";
return;
}
eval {
alarm(10000);
$SIG{'ALRM'} = sub {
print "Timeout while building $pkg\n";
die;
};
#we should keep track of how many times the port fails
#to install then then run make distclean after the 10th
#time
#right now we just run it every time
$ENV{'BATCH'} = 'yes';
if ( $pkg =~ /mysql.*server/ ) { checkbrokenmysql(); }
if ( -e '/usr/local/sbin/portupgrade' && $pkg !~ /portupgrade/ ) {
my $npath = $path;
$npath =~ s/^\/usr\/ports\///g;
my $args = ( $has ? '-' : '-N' ) . ( $force ? 'fO' : '' ) . 'rv';
system( '/usr/local/sbin/portupgrade', $args, $npath );
}
else {
system('make distclean');
if ( $virginpkg =~ /^expect/ ) {
print "Building Expect with special plans...\n";
system('make -DWITHOUT_X11');
system('make -DWITHOUT_X11 install');
installbsdpkg('expect');
}
else {
system('make');
if ( $? != 0 && $? != 1 ) {
print "There was a problem building the port!\n";
system('make distclean');
return 0;
}
system('make deinstall');
system('make deinstall');
system('make install');
}
system('make clean');
}
postinstall($virginpkg);
alarm(0);
};
return;
}
sub getpkgverdir {
my ( $pkg, $mon, $mday, $year, $exactmatch ) = @_;
my $foundpkg = 0;
my $dir;
my $pkgn;
open( INDEX, "/root/.cpbsdpkgs/${mon}-${mday}-${year}.INDEX" );
while (<INDEX>) {
chomp();
( $pkgn, $dir, undef ) = split( /\|/, $_ );
if ($exactmatch) {
if ( $pkgn eq $pkg ) {
$foundpkg = 1;
last;
}
}
else {
if ( $pkg =~ /-[\.\d]+$/ || $pkg =~ /^compat/ ) {
if ( Cpanel::StringFunc::ibeginmatch( $pkgn, $pkg ) ) {
$foundpkg = 1;
last;
}
}
else {
my $pkgname = gettruename($pkgn);
if ( $pkgname eq ${pkg} ) {
$foundpkg = 1;
last;
}
}
}
}
close(INDEX);
$dir =~ s/^\/usr\/ports\///g;
$dir =~ s/[^\/]+$//g;
$dir =~ s/\/$//g;
return ( $pkgn, $dir, $foundpkg );
}
sub getportversion {
my ($dir) = @_;
my ( $version, $release );
my $pkginfo = `cd ${dir};make describe`;
chomp($pkginfo);
my ($pkgn);
( $pkgn, undef ) = split( /\|/, $pkginfo );
my $pkgname = gettruename($pkgn);
$pkgn =~ s/^\Q${pkgname}\E-//g;
return ( "${pkgn}", $pkgname );
}
sub saferunnoerror {
my (@PROGA) = @_;
my ($output);
open( WNULL, ">/dev/null" );
open( RNULL, "</dev/null" );
my $pid = open3( "<&RNULL", \*MPROG, ">&WNULL", @PROGA );
while (<MPROG>) { $output .= $_; }
close(MPROG);
close(RNULL);
close(WNULL);
waitpid($pid,0);
return ($output);
}
sub safepkg {
my (@PROGA) = @_;
my ($output);
open( RNULL, "</dev/null" );
my $pid = open3( "<&RNULL", ">&STDOUT", \*MPROG, @PROGA );
while (<MPROG>) {
if ( !/has no origin recorded/ ) { print; }
}
close(MPROG);
close(RNULL);
waitpid($pid,0);
}
sub gettruename {
my ($name) = @_;
$name =~ s/-\d+[^-]*$//g;
return ($name);
}
sub getpkginfo {
my ($pkginfo) = @_;
my $pkgdate;
my $oldpkgdate;
my $pkg;
my $now = time();
my ( $mday, $mon, $year );
( undef, undef, undef, $mday, $mon, $year, undef, undef, undef ) = localtime($now);
$year += 1900;
$mon++;
if ("/root/.cpbsdpkgs/${mon}-${mday}-${year}.PKGDATE") {
open( PKGDATE, "/root/.cpbsdpkgs/${mon}-${mday}-${year}.PKGDATE" );
$oldpkgdate = int(<PKGDATE>);
close(PKGDATE);
}
$pkgdate = $oldpkgdate;
opendir( PKGD, '/var/db/pkg' );
my @PG = readdir(PKGD);
closedir(PKGD);
foreach my $testpkg (@PG) {
next if (/^\./);
my $mtime = ( stat("/var/db/pkg/${testpkg}") )[9];
if ( $mtime > $pkgdate && $mtime <= $now ) { $pkgdate = $mtime; } #timewarp safe
}
my $mtime = ( stat("/var/db/pkg") )[9];
if ( $mtime > $pkgdate && $mtime <= $now ) { $pkgdate = $mtime; } #timewarp safe
if ( $pkgdate > $oldpkgdate ) {
unlink("/root/.cpbsdpkgs/${mon}-${mday}-${year}.PKGINFO");
}
open( PKGDATE, ">/root/.cpbsdpkgs/${mon}-${mday}-${year}.PKGDATE" );
print PKGDATE $pkgdate;
close(PKGDATE);
if ( -e "/root/.cpbsdpkgs/${mon}-${mday}-${year}.PKGINFO" ) {
open( PKGINFO, "/root/.cpbsdpkgs/${mon}-${mday}-${year}.PKGINFO" );
if ( $pkginfo ne '' ) {
while (<PKGINFO>) { $pkg .= $_; }
}
else {
while (<PKGINFO>) {
if (/^${pkginfo}/) { $pkg .= $_; }
}
}
close(PKGINFO);
return $pkg;
}
else {
$pkg = `pkg_info`;
open( PKGINFO, ">/root/.cpbsdpkgs/${mon}-${mday}-${year}.PKGINFO" );
print PKGINFO $pkg;
close(PKGINFO);
if ( $pkginfo eq "" ) {
return ($pkg);
}
else {
my @PKG = split( /\n/, $pkg );
@PKG = grep( /^\Q${pkginfo}\E/, @PKG );
$pkg = join( "\n", @PKG );
return ($pkg);
}
}
}
sub checkbrokenmysql {
#fixed in latest mysql version.. hopefully
return ();
my ( $sysname, $nodename, $release, $version, $machine ) = Cpanel::OSSys::uname();
if ( $sysname ne "FreeBSD" || $machine !~ /64/ ) { return (); }
my (@CFILE);
# no sense to create a blank copy of this file
my $slock = Cpanel::SafeFile::safeopen( \*MM, "+<", "/usr/ports/databases/mysql40-server/Makefile" );
if( !$slock ) {
$logger->die("Could not edit /usr/ports/databases/mysql40-server/Makefile");
}
while (<MM>) {
next if (/with-libwrap/);
push( @CFILE, $_ );
}
seek( MM, 0, 0 );
print MM join( "", @CFILE );
truncate( MM, tell(MM) );
Cpanel::SafeFile::safeclose( \*MM, $slock );
}
1;