#!/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
# cPGSD Installer                 Copyright(c) cPanel, Inc.
#                                 All rights Reserved.
# darren@cpanel.net               http://cpgs.cpanel.net
#

use Socket;
$| = 1;

if ( $< != 0 ) {
    print "You must be root to install cPGS.\n";
    exit(0);
}

my $release = '';
if ( open( my $cfg_fh, '<', '/var/cpanel/cpgs/cpgsd.cfg' ) ) {
    while (<$cfg_fh>) {
        my ( $var, $val ) = split( /\=/, $_, 2 );
        if ( $var eq 'disableupdates' && $val == 1 ) {
            print "Updates are currently disabled, please edit /var/cpanel/cpgs/cpgsd.cfg and set disableupdates=0 to enable.\n";
        } elsif( $var eq 'release' ) {
            if( $val =~ m/beta/i ) {
                $release = 'beta';
            }
        }
    }
    close($cfg_fh);
}

my $orig_umask = umask;
umask(0022);

mkdir '/var/cpanel/cpgs/tmp';

if ( !-d '/var/cpanel/cpgs' ) {
    print "Creating cpanel directory /var/cpanel/cpgs ..\n";
    system( 'mkdir', '-p', '/var/cpanel/cpgs' );
}

print "Downloading and installing the daemon files.. (this should take less than a minute)\n";
$pkgurl = "/$release/GameServerAddon/daemon.tgz";
my $randNum = rand $$ * 1000;
$pkgname = "cPGSUpdate\.$$\.$randNum\.tgz";
$host    = 'cpgs.cpanel.net';
$iaddr   = inet_aton($host) || print("Failed to find host: $host : $!");
$paddr   = sockaddr_in( 80, $iaddr ) || print("Something went wrong: $!");
$proto   = getprotobyname('tcp') || print("Unable to get protocol: $!");
socket( SOCK, PF_INET, SOCK_STREAM, $proto ) || print("Failed to open socket: $!");
connect( SOCK, $paddr ) || die print("Unable to connect: $!");
$submit = "GET $pkgurl HTTP/1.1\nHost: $host\n\n";
send( SOCK, $submit, 0 );
shutdown( SOCK, 1 );
my $httpcode = <SOCK>;
if ( $httpcode !~ /^HTTP\/1\..\s+200\s+OK/ ) { print "There was a problem! $httpcode<br>\n"; }

while ( <SOCK> =~ m/^(\S+):\s+(.+)/ ) {
    if ( $1 eq "Content-Length" ) {
        $size = $2;
        $size =~ s/(\r|\n)//g;
    }
    next;
}

print "Downloading $size bytes to /tmp/$pkgname\n";
open( my $tmp_fh, '>', '/tmp/' . $pkgname ) or die "Could not open /tmp/$pkgname for writing, update aborted.<br>\n";
binmode $tmp_fh;
while (<SOCK>) {
    print {$tmp_fh} $_;
}
close($tmp_fh);
close(SOCK);

chdir("/var/cpanel/") or print "Could not change directory to /var/cpanel : $!\n";
`tar xzvf /tmp/$pkgname -C /var/cpanel`;
unlink("/tmp/$pkgname");

# get rid of old generic server files
system('rm','-rf','/var/cpanel/cpgs/games/generic/');

# Check for generic installers for required packages, add new systems as discovered
if( -x '/usr/bin/yum' ) {
    if(! -x '/usr/bin/gcc') {
        system('/usr/bin/yum','-y','install', 'gcc');
    }
    if(! -e '/lib/ld-linux.so.2') {
        system('/usr/bin/yum','-y','install', 'glibc.i686');
    }
    if(! -e '/usr/lib/libstdc++.so.6') {
        system('/usr/bin/yum','-y','install', 'libstdc++.i686');
    }
    if(! -e '/usr/lib/libstdc++.so.5') {
        system('/usr/bin/yum','-y','install', 'compat-libstdc++-33.i686');
    }
    if(! -e '/usr/include/openssl/blowfish.h') {
        system('/usr/bin/yum','-y','install', 'openssl-devel');
    }
    if(! -e '/usr/include/sys/resource.h') {
        system('/usr/bin/yum','-y','install', 'glibc-headers');
    }
    if(! -e '/usr/bin/uudecode') {
        system('/usr/bin/yum','-y','install', 'sharutils');
    }

} elsif( -x '/usr/bin/pacman' ) {
    if(! -e '/usr/bin/gcc') {
        system('/usr/bin/pacman','-S','--noconfirm', 'gcc');
    }
    if(! -e '/usr/lib32/libstdc++.so.6') {
        system('/usr/bin/pacman','-S','--noconfirm', 'lib32-gcc-libs');
    }
    if(! -e '/lib/ld-linux.so.2') {
        system('/usr/bin/pacman','-S','--noconfirm', 'multilib/lib32-glibc');
    }
    if(! -e '/usr/lib/libstdc++.so.5') {
        system('/usr/bin/pacman','-S','--noconfirm', 'extra/libstdc++5');
    }
    if(! -e '/usr/include/openssl/blowfish.h') {
        system('/usr/bin/pacman','-S','--noconfirm', 'openssl');
    }
}

if ( !-e "/var/cpanel/cpgs/cpgs.pem" ) {
    print "\nCreating new SSL cert/key PEM /var/cpanel/cpgs/cpgs.pem ..\n";
    open( OPENSSL, "|-" ) || exec(
        "openssl",
        "req",     "-new", "-x509",
        "-days",   "365",  "-nodes",
        "-out",    "/var/cpanel/cpgs/cpgs.pem",
        "-keyout", "/var/cpanel/cpgs/cpgs.pem"
    );

    print OPENSSL "US
Unknown
Unknown
Unknown
Unknown
cPGSD
ssl@cpanel.net\n";

    close(OPENSSL);

}

print "\n";
chmod( 0644, '/var/cpanel/cpgs/cpgs.pem' );

if ( !-d '/usr/local/cpanel/libexec' ) {
    system( 'mkdir', '-p', '/usr/local/cpanel/libexec' );
}

# if ( !-f '/usr/local/cpanel/libexec/cpgsd.pl' and -f '/var/cpanel/cpgsd.pl' ) {
    # system( '/bin/mv', '/var/cpanel/cpgsd.pl', '/usr/local/cpanel/libexec/cpgsd.pl' );
# }

unlink '/usr/local/cpanel/libexec/cpgsd.pl';
system( '/bin/mv', '/var/cpanel/cpgsd.pl', '/usr/local/cpanel/libexec/cpgsd.pl' );
my $inode_one = ( stat('/usr/local/cpanel/libexec/cpgsd.pl') )[1];
my $inode_two = ( stat('/var/cpanel/cpgsd.pl') )[1];
if ( $inode_one != $inode_two ) {
    rename( '/var/cpanel/cpgsd.pl', '/var/cpanel/cpgsd.pl.old' );
    system( 'ln', '-sf', '/usr/local/cpanel/libexec/cpgsd.pl', '/var/cpanel/cpgsd.pl' );
}

#### create a cpgsd.cfg if none exists ####################################

if ( !-e "/var/cpanel/cpgs/cpgsd.cfg" ) {
    print "Creating /var/cpanel/cpgs/cpgsd.cfg ..\n";

    # get a list of all IPs bound to the server and allow them to talk to cPGSD by default.
    my $boundips;
    my @ifconfig = `ifconfig`;
    foreach my $line (@ifconfig) {
        if ( $line =~ m/\s*inet\s(\d+)\.(\d+)\.(\d+)\.(\d+)\s+/ ) {    # bsd
            $boundips .= "$1\.$2\.$3\.$4,";
        }
        elsif ( $line =~ m/\s*inet\s+addr\:(\d+)\.(\d+)\.(\d+)\.(\d+)\s+/ ) {    # linux
            $boundips .= "$1\.$2\.$3\.$4,";
        }
    }

    open( my $config_fh, '>', '/var/cpanel/cpgs/cpgsd.cfg' ) or print "Could not write default config to /var/cpanel/cpgs/cpgsd.cfg : $!\n";
    print $config_fh <<EOF;
root=/var/cpanel/
allowedips=$boundips
sslpem=/var/cpanel/cpgs.pem
pkgdir=/home/gameservers/
qstat=/usr/local/bin/qstat
logfile=/var/log/cpgsd.log
root=/var/cpanel
port=2092
maxsim=2
waittime=10
quotacheck=1
EOF
    close($config_fh);

}

print "\nPreparing cPGSD Config ..\n";

# add current SSH IP to the list, allows for frontend servers to set up remote backend servers
my ($sship,undef) = split(/\s+/,$ENV{'SSH_CONNECTION'});
if($sship =~ m/^\d+\.\d+\.\d+\.\d+$/) {
    if(open( my $config_fh, '<', '/var/cpanel/cpgs/cpgsd.cfg' )) {
        my @cfg = (<$config_fh>);
        close($config_fh);

        if(open( my $config_fh, '>', '/var/cpanel/cpgs/cpgsd.cfg' )) {
            foreach my $line(@cfg) {
                if($line =~ m/^allowedips=(.*)/) {
                    my $all = $1;
                    my @aips = split(/\,/,$all);
                    my $matched = 0;
                    foreach my $i_p(@aips) {
                        if($i_p eq $sship) {
                            $matched = 1;
                            last;
                        }
                    }
                    if($matched == 0) {
                        print $config_fh "allowedips=$all\,$sship\n";
                    } else {
                        print $config_fh $line;
                    }
                } else {
                    print $config_fh $line;
                }
            }
        }
    }
}

system( '/usr/local/cpanel/libexec/cpgsd.pl', 'prep' );

print "Setting up cron jobs ..\n";

$fnd  = 0;
$fnd2 = 0;
open( my $ctab, '<', '/etc/crontab' );
@croncont = (<$ctab>);
close($ctab);
if ( grep /cpgs_cron/, @croncont ) { $fnd  = 1; }
if ( grep /cpgs_chk/,  @croncont ) { $fnd2 = 1; }


my $bucnt = 0;
my @bulist;

if ( opendir( my $etc_fh, '/etc' ) ) {
    while ( my $file = readdir($etc_fh) ) {
        if ( $file =~ m/^crontab\.\d{10}/ ) {
            $bucnt++;
            push( @bulist, $file );
        }
    }
    closedir($etc_fh);
}
else {
    print "Could not open /etc , terminating update/install : $!\n";
    exit;
}

if ( $bucnt > 4 ) {
    print "Deleteing oldest backup file..\n";
    my @sorted = sort(@bulist);
    my $oldest = '/etc/' . shift(@sorted);
    if ( -f $oldest and !-l $oldest ) {
        unlink($oldest);
    }
}

BACKUP:
my $time   = time;
my $backup = "/etc/crontab.$time";

if ( !-e $backup ) {
    print "Backing up /etc/crontab to $backup<br>\n";
    if ( open( my $crontabcopy_fh, '>', $backup ) ) {
        foreach (@croncont) {
            print $crontabcopy_fh $_;
        }
        close($crontabcopy_fh);
    }
    else {
        print "Could not create $backup : $! <br>\n";
    }
}
else {
    sleep 1;
    goto BACKUP;
}

if ( $fnd == 0 ) {
    print "Adding cpgs_cron.pl script to /etc/crontab..<br>\n";
    push(@croncont, "*/2 * * * * root /var/cpanel/cpgs/cpgs_cron.pl\n");
}
if ( $fnd2 == 0 ) {
    print "Adding cpgs_chk script to /etc/crontab..<br>\n";
    push(@croncont, "*/5 * * * * root /var/cpanel/cpgs/cpgs_chk 2>&1 >>/var/log/cpgsd.log\n");
}

if ( open( my $crontab_fh, '>', '/etc/crontab' ) ) {
    foreach my $line (@croncont) {
        if ( $line =~ m/(.*)cpgs_cron/ ) {
            if ( $1 =~ m/^\#/ ) {
                print $crontab_fh "\n\#* * * * * root /var/cpanel/cpgs/cpgs_cron.pl\n";
            }
            else {
                print $crontab_fh "\n* * * * * root /var/cpanel/cpgs/cpgs_cron.pl\n";
            }
        }
        elsif ( line =~ m/(.*)cpgs_chk/ ) {
            if ( $1 =~ m/^\#/ ) {
                print $crontab_fh "\n\#*/5 * * * * root /var/cpanel/cpgs/cpgs_chk 2>&1 >>/var/log/cpgsd.log\n";
            }
            else {
                print $crontab_fh "\n*/5 * * * * root /var/cpanel/cpgs/cpgs_chk 2>&1 >>/var/log/cpgsd.log\n";
            }
        }
        else {
            print $crontab_fh $line;
        }
    }
}
else {
    print "Could not write to /etc/crontab : $! <br>\n";
}
close($crontab_fh);

# done with crontabs

if ( open( my $alertcfg, '<', '/var/cpanel/cpgs/alert.cfg' ) ) {
    while (<$alertcfg>) {
        if (m/darren\@cpanel/) {
            close($alertcfg);
            unlink '/var/cpanel/cpgs/alert.cfg';
            last;
        }
    }
}

print "#" x 50;
print "\n\n";
print <<EOF;

cPGSD is now installed, please edit /var/cpanel/cpgs/cpgsd.cfg as needed.
Be sure to set the pkgdir= to the path where your .cpgs files are located before starting cPGSD.
You can start the cPGSD daemon with the following command as root via SSH:


`/usr/local/cpanel/libexec/cpgsd.pl`

EOF

print "#" x 50;
print "\n\n";

chmod oct('0700'), '/var/cpanel/cpgs/cpgs_cron.pl';
chmod oct('0700'), '/var/cpanel/cpgs/cpgs_chk';
chmod oct('0700'), '/usr/local/cpanel/libexec/cpgsd.pl';

umask($orig_umask);

system('/var/cpanel/cpgs/misc/config_convert.pl');
system('/usr/local/cpanel/libexec/cpgsd.pl');
print "execed..<br>\n";
exit(0);

