#!/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
#####################################################################
# make_patch                      Copyright(c) cPanel, Inc. 2011
#                                 All rights Reserved.
# darren@cpanel.net               http://cpgs.cpanel.net
#####################################################################
# Create a patch file based on the difference of two directories.

use strict;
use File::Find;
use Digest::MD5;

my $patchfile = shift;
my @dirs = @ARGV;
my $dcnt = @dirs;
if($dcnt != 2) {
    showusage();
}
foreach my $dir(@dirs) {
    if(! -d $dir) {
        print "Bad directory given ( $dir ): $!\n";
        showusage();
    }
}
print "Saving file diffs to $patchfile\n";
my ($olddir,$newdir) = @dirs;
$olddir =~ s/\/$//g;
$newdir =~ s/\/$//g;

my %old;
my %new;

$ENV{'CPGSFIND'} = 'old';
find(\&wanted,  $olddir);
$ENV{'CPGSFIND'} = 'new';
find(\&wanted,  $newdir);

my %tracked;

foreach my $file(keys %old) {
    $file =~ s/^.*($olddir|$newdir)//; # strip off base directory name

    if( ! defined( $new{$file}{'md5'} ) ) {
        $tracked{$file}{'status'} = 'delete';
    }
    elsif( $old{$file}{'md5'} ne $new{$file}{'md5'} ) {
        $tracked{$file}{'status'} = 'replace';
    }
}

foreach my $file(keys %new) {
    $file =~ s/^.*($olddir|$newdir)//; # strip off base directory name
    if( ! defined( $old{$file}{'md5'} ) ) {
        $tracked{$file}{'status'} = 'add';
    }
}

my $randdir = get_rand_string(20);
my $tmpdir = '/tmp/cpgs_patch_' . $randdir;

if( -e $tmpdir ) {
    print "Temporary directory $tmpdir already exists..\n";
    exit;
} else {
    mkdir $tmpdir;
}

my $pkg_list = $tmpdir . '.pkglist';
my $pre = $tmpdir . '.pre';

if( open( my $pre_fh, '>', $pre ) ) {
    print {$pre_fh} <<EOF;
#!/usr/bin/perl
# auto-generated pre install/upgrade script

my \@rmfiles = (
EOF

    if( open( my $copy_files_fh, '>', $pkg_list ) ) {
        foreach my $pfile(sort keys %tracked) {
            if( $tracked{$pfile}{'status'} =~ m/^replace|add$/ ) {
                print {$copy_files_fh} "$pfile\n";
            } elsif( $tracked{$pfile}{'status'} eq 'delete' ) {
                $pfile =~ s/^\///;
                print {$pre_fh} "   '$pfile',\n";
            }
        }
        close($copy_files_fh);
    } else {
        print "Could not create package list $pkg_list: $!\n";
        exit;
    }
    print {$pre_fh} <<EOF2;
);

foreach my \$file(\@rmfiles) {
    if( -f \$file || -d \$file ) {
        system("rm","-rf",\$file);
    }
}
EOF2
    close($pre_fh);
} else {
    print "Could not open pre install/update script $pre for writing : $!\n";
    exit;
}

print "Edit file list ? ";
my $input = <STDIN>;
if($input =~ m/^y/i) {
    system("nano",$pkg_list);
}
print "Copying files to temporary patch directory $tmpdir..\n";

system("rsync","-rv","--files-from=$pkg_list",$newdir,$tmpdir);

print "itag=";
chomp(my $itag = <STDIN>);

print "name=";
chomp(my $name = <STDIN>);

print "vers=";
chomp(my $vers = <STDIN>);

print "desc=";
chomp(my $desc = <STDIN>);

# call cpgs_pkg to make package from our temp directory w/ pre script

system("/var/cpanel/cpgs/cpgs_pkg","-p","itag=$itag","name=$name","vers=$vers","gdir=$tmpdir","file=$patchfile","pre=$pre","desc=$desc","type=patch");

# clean up
if(-d $tmpdir && $tmpdir =~ m/^\/tmp\//) {
    system('rm','-rf',$tmpdir)
}
exit;

####################################################33

sub wanted {
    my $f = $_;
    if( -f $f) {
        if(open(my $fh, $f)) {
            binmode($fh);
            my $fname = $File::Find::name;
            $fname =~ s/^.*($olddir|$newdir)//; # strip off base directory name
            my $md5_hex = Digest::MD5->new->addfile(*$fh)->hexdigest;
            if( $ENV{'CPGSFIND'} eq 'old') {
                $old{$fname}{'md5'} = $md5_hex;
            } else {
                $new{$fname}{'md5'} = $md5_hex;
            }
            close($fh);
        } else {
            print "Could not open $f : $!\n";
            exit;
        }
    }
}


sub showusage {
    print "\n\tUsage:\n\t\t$0 <patchfile.cpgs> <old version directory> <new version directory>\n\n";
    exit;
}

sub get_rand_string {
    my ($length) = @_;
    my @chars = ( 'a' .. 'z', 'A' .. 'Z', 0 .. 9 );
    my $return;
    foreach ( 1 .. $length ) {
        $return .= $chars[ rand(@chars) ];
    }
    return $return;
}
