#!/usr/bin/perl
# cpanel12 - scripts                              Copyright(c) 2008 cPanel, Inc.
#                                                           All rights Reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cpanel license. Unauthorized copying is prohibited
# $Desc: v3.0.0-274-g545221d$

use strict;
use warnings;

use POSIX ();

$| = 1;

my $user = $ARGV[0];

my ( $system, $release, $machine ) = ( POSIX::uname() )[ 0, 2, 4 ];

my $dotbuffer = '/scripts/dotbuffer';
if ( !-e "/scripts/dotbuffer" ) {
    my $tmpdir = ( getpwuid($>) )[7] . "/tmp";
    mkdir( $tmpdir, 0700 );
    open( DOTBUFFER, ">$tmpdir/dotbuffer" );
    print DOTBUFFER <<EOM;
#!/usr/bin/perl
\$limit = \$ARGV[0];
\$|=1;
while(read(STDIN,\$buffer,1)) {
       if (\$buffer =~ /a/i || \$buffer =~ /b/i) {
               print ".";
               \$count++;
               if (\$count == \$limit) {
                       print "\n";
                       \$count=0;
               }
       }
}
EOM
    close(DOTBUFFER);
    chmod( 0700, "$tmpdir/dotbuffer" );
    $dotbuffer = "$tmpdir/dotbuffer";
}

if ( $user eq "root" ) {
    print "You cannot copy the root user.\n";
    exit;
}
my $tarroot  = $ARGV[1];
my $isbackup = 0;
my $prefix;
if ( $ARGV[2] eq "backup" ) {
    $isbackup = 1;
    $prefix   = '';
}
else {
    $prefix = 'cpmove-';
}

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

if ( $tarroot eq "" || !-d "$tarroot" ) {
    if ( $ARGV[2] eq "backup" ) {
        print "Bailing out.. you must set a valid destination for backups\n";
        exit;
    }
    $tarroot = '/home';
}

if ( !getpwnam($user) ) {
    print "Invalid Account\n";
    exit;
}

my $homedir     = ( getpwnam($user) )[7];
my $truehomedir = ( getpwnam($user) )[7];
my $skipacctdb  = pop(@ARGV) eq '--skipacctdb';

$homedir .= "/public_html";

if ( -l $homedir ) {
    $homedir = readlink($homedir);
}

$homedir =~ /([^\/]+)$/;

my $dns   = $1;
my $lcdns = lc($1);

if ( $dns eq "" ) {
    print "Unable to find domain name for $user\n";
    exit;
}

print "dXm DNS is $dns\n";

if ( $prefix eq "" && $tarroot eq "/home" ) {
    print "Bailing out .. no prefix set and tarroot is /home\n";
    exit;
}

my $domainmap = ( -e '/etc/dsm.domainmap' ) ? '/etc/dsm.domainmap' : '/var/db/dsm/conf/domainmap';
my %DOMAINS;
open( DNSMAP, $domainmap );
while (<DNSMAP>) {
    s/\n//g;
    s/\s//g;
    my ( $mdomain, $muser ) = split( /:/, $_ );
    next if ( $muser ne $user );
    $DOMAINS{$mdomain} = 1;
}
close(DNSMAP);

if ( $prefix ne "" ) {
    if ( -d "${tarroot}/${prefix}${user}" && !-l "${tarroot}/${prefix}${user}" ) {
        system( "rm", "-rf", "${tarroot}/${prefix}${user}" );
    }
    if ( -f "${tarroot}/${prefix}${user}.tar.gz" && !-l "${tarroot}/${prefix}${user}.tar.gz" ) {
        system( "rm", "-rf", "${tarroot}/${prefix}${user}.tar.gz" );
    }
}

open( CPM, ">${tarroot}/${prefix}${user}.tar.gz" );
close(CPM);
chmod( 0600, "${tarroot}/${prefix}${user}.tar.gz" );

if ( !-e "${tarroot}/${prefix}${user}" ) {
    mkdir( "${tarroot}/${prefix}${user}",          0700 );
    mkdir( "${tarroot}/${prefix}${user}/cp",       0700 );
    mkdir( "${tarroot}/${prefix}${user}/logs",     0700 );
    mkdir( "${tarroot}/${prefix}${user}/mysql",    0700 );
    mkdir( "${tarroot}/${prefix}${user}/mm",       0700 );
    mkdir( "${tarroot}/${prefix}${user}/mma",      0700 );
    mkdir( "${tarroot}/${prefix}${user}/mma/pub",  0700 );
    mkdir( "${tarroot}/${prefix}${user}/mma/priv", 0700 );
    mkdir( "${tarroot}/${prefix}${user}/va",       0700 );
    mkdir( "${tarroot}/${prefix}${user}/fp",       0700 );
    mkdir( "${tarroot}/${prefix}${user}/vf",       0700 );
}
else {
    print "${tarroot}/${prefix}${user} exists, please remove it and try again\n";
    exit;
}

foreach my $mdomain ( sort keys %DOMAINS ) {
    print $mdomain . "\n";
    if ( -e "/usr/local/frontpage/${mdomain}:80.cnf" ) {
        print "Copying frontpage file....";
        system( "cp", "/usr/local/frontpage/${mdomain}:80.cnf", "${tarroot}/${prefix}${user}/fp" );
        print "Done\n";
    }
}

print "dXm Copying Mail files....";
foreach my $mdomain ( sort keys %DOMAINS ) {
    system( "cp", "-a", "/etc/courier/aliases/$mdomain", "${tarroot}/${prefix}${user}/va/$mdomain" );
    open( VA, ">>${tarroot}/${prefix}${user}/va/$mdomain" );
    print VA "*: $user\n";
    close(VA);
}
print "Done\n";

print "dXm Copying proftpd file....";
my @WEBUSERS;
open( PROFTPDPASS, ">${tarroot}/${prefix}${user}/proftpdpasswd" );
open( USERS,       "/etc/ftp.passwd" );
while (<USERS>) {
    s/\n//g;
    if (/^${user}_/) {
        s/^${user}_//g;
        my ( $webuser, $spass );
        ( $webuser, $spass, undef ) = split( /:/, $_, 2 );
        push( @WEBUSERS, $webuser );
        print PROFTPDPASS "${webuser}:${spass}:-1:-1::/dev/null:/bin/ftpsh\n";
    }
}
close(PROFTPDPASS);
print "Done\n";

print "Copying www logs....";
foreach my $domain ( sort keys %DOMAINS ) {
    if ( my $pid = fork() ) {
        my $dotcount = 5;
        while ( waitpid( $pid, 1 ) != -1 ) {
            if ( $dotcount % 5 == 0 ) {
                print ".........\n";
            }
            sleep(1);
            $dotcount++;
        }
    }
    else {
        $0 = "pkgacct - ${user} - log copy child";
        system("cp /usr/local/apache/domlogs/${domain}* ${tarroot}/${prefix}${user}/logs 2>/dev/null");
        system("cp /usr/local/apache/domlogs/www.${domain}* ${tarroot}/${prefix}${user}/logs 2>/dev/null");
        system("cp /usr/local/apache/domlogs/ftp.${domain}* ${tarroot}/${prefix}${user}/logs 2>/dev/null");
        exit;
    }
}
print "Done\n";

unless ($skipacctdb) {
    print "dXm Grabbing mysql dbs...";
    my ($mysqluser) = $user;
    $mysqluser =~ s/-//g;
    if ( $system =~ /freebsd/i ) {
        system("cp -Rp /var/lib/mysql/${user}_* ${tarroot}/${prefix}${user}/mysql 2>/dev/null");
        system("cp -Rp /var/lib/mysql/${user} ${tarroot}/${prefix}${user}/mysql 2>/dev/null");
        system("cp -Rp /var/lib/mysql/${mysqluser}_* ${tarroot}/${prefix}${user}/mysql 2>/dev/null");
        system("cp -Rp /var/lib/mysql/${mysqluser} ${tarroot}/${prefix}${user}/mysql 2>/dev/null");
    }
    else {
        system("cp -a /var/lib/mysql/${user}_* ${tarroot}/${prefix}${user}/mysql 2>/dev/null");
        system("cp -a /var/lib/mysql/${user} ${tarroot}/${prefix}${user}/mysql 2>/dev/null");
        system("cp -a /var/lib/mysql/${mysqluser}_* ${tarroot}/${prefix}${user}/mysql 2>/dev/null");
        system("cp -a /var/lib/mysql/${mysqluser} ${tarroot}/${prefix}${user}/mysql 2>/dev/null");
    }
    print "Done\n";
}

print "dXm Copying homedir....";
if ( my $pid = fork() ) {
    my $dotcount = 5;
    while ( waitpid( $pid, 1 ) != -1 ) {
        if ( $dotcount % 5 == 0 ) {
            print ".........\n";
        }
        sleep(1);
        $dotcount++;
    }
}
else {
    system( "cp", "-a", "$truehomedir", "${tarroot}/${prefix}${user}/homedir" );
    exit();
}
print "Done\n";

system( "rm", "-f", "${tarroot}/${prefix}${user}/homedir/public_html" );
system("mv ${tarroot}/${prefix}${user}/homedir/wwwroot/$dns ${tarroot}/${prefix}${user}/homedir/public_html 2>/dev/null");
system("mv ${tarroot}/${prefix}${user}/homedir/stats ${tarroot}/${prefix}${user}/homedir/tmp 2>/dev/null");
system("mv ${tarroot}/${prefix}${user}/homedir/tmp/webalizer/${dns}/* ${tarroot}/${prefix}${user}/homedir/tmp/webalizer/ 2>/dev/null");
my @PPDS;
my @SDS;
foreach my $mdomain ( sort keys %DOMAINS ) {
    next if ( $mdomain eq $dns );
    my $subdn = $mdomain;
    $subdn =~ s/\.//g;
    push( @PPDS, "${mdomain}=${subdn}_${dns}" );
    push( @SDS,  $subdn );
    system("mv ${tarroot}/${prefix}${user}/homedir/wwwroot/$mdomain ${tarroot}/${prefix}${user}/homedir/public_html/$subdn 2>/dev/null");
}

print "Storing Subdomains....\n";
open( SH, ">${tarroot}/${prefix}${user}/sds" );

foreach my $domain ( sort keys %DOMAINS ) {
    my @SSD = listsubdomains($domain);
    foreach my $sd (@SSD) {
        print SH "${sd}_${domain}\n";
    }

}
foreach my $sd (@SDS) {
    print SH "${sd}_${dns}\n";
}
close(SH);
print "Done\n";

print "Storing Parked Domains....\n";
open( SH, ">${tarroot}/${prefix}${user}/pds" );
foreach my $sd (@PPDS) {
    print SH "$sd\n";
}
close(SH);
print "Done\n";

mkdir( "${tarroot}/${prefix}${user}/homedir/etc",  0700 );
mkdir( "${tarroot}/${prefix}${user}/homedir/mail", 0755 );

foreach my $mdomain ( sort keys %DOMAINS ) {
    mkdir( "${tarroot}/${prefix}${user}/homedir/mail/${mdomain}", 0700 );
    mkdir( "${tarroot}/${prefix}${user}/homedir/etc/${mdomain}",  0700 );
    opendir( POPS, "${tarroot}/${prefix}${user}/homedir/popaccts/$mdomain" );
    my @POPS = readdir(POPS);
    @POPS = grep( !/^\./, @POPS );
    closedir(POPS);
    foreach my $pop (@POPS) {
        print "Building mbox for $pop\@${mdomain}....";
        mkdir( "${tarroot}/${prefix}${user}/homedir/mail/${mdomain}/${pop}", 0750 );
        opendir( POPSF, "${tarroot}/${prefix}${user}/homedir/popaccts/${mdomain}/${pop}/Maildir/new" );
        my @POPSF = readdir(POPSF);
        @POPSF = grep( !/^\./, @POPSF );
        closedir(POPSF);

        open( MBOX, ">${tarroot}/${prefix}${user}/homedir/mail/${mdomain}/${pop}/inbox" );
        chmod( 0660, "${tarroot}/${prefix}${user}/homedir/mail/${mdomain}/${pop}/inbox" );

        foreach my $msg ( sort { $a <=> $b } @POPSF ) {
            print ".";
            open( MSG, "${tarroot}/${prefix}${user}/homedir/popaccts/${mdomain}/${pop}/Maildir/new/$msg" );
            while (<MSG>) {
                print MBOX;
            }
            close(MSG);
        }
        close(MBOX);
        print "Done\n";

        my ($cpass);
        open( PU, "/etc/courier/userdb/$mdomain" );
        while (<PU>) {
            if (/^${pop}\@/) {
                /systempw=([^\|]+)/;
                $cpass = $1;
                last;
            }
        }
        close(PU);

        my @passwd = getpwnam($user);
        open( PASSWD, ">>${tarroot}/${prefix}${user}/homedir/etc/${mdomain}/passwd" );
        print PASSWD "${pop}:x:$passwd[2]:$passwd[3]:${user}:/home/${user}:/bin/bash\n";
        close(PASSWD);
        chmod( 0600, "${tarroot}/${prefix}${user}/homedir/etc/${mdomain}/shadow" );
        open( PASSWD, ">>${tarroot}/${prefix}${user}/homedir/etc/${mdomain}/shadow" );
        print PASSWD "${pop}:${cpass}:::::::\n";
        close(PASSWD);
        chmod( 0600, "${tarroot}/${prefix}${user}/homedir/etc/${mdomain}/shadow" );

    }

}

print "Building Default mbox...";
opendir( POPSF, "${tarroot}/${prefix}${user}/homedir/Maildir/new" );
my @POPSF = readdir(POPSF);
@POPSF = grep( !/^\./, @POPSF );
closedir(POPSF);

open( MBOX, ">${tarroot}/${prefix}${user}/homedir/mail/inbox" );
chmod( 0660, "${tarroot}/${prefix}${user}/homedir/mail/inbox" );

foreach my $msg ( sort { $a <=> $b } @POPSF ) {
    print ".";
    open( MSG, "${tarroot}/${prefix}${user}/homedir/Maildir/new/$msg" );
    while (<MSG>) {
        print MBOX;
    }
    close(MSG);
}
close(MBOX);
print "Done\n";

system( "rm", "-rf", "${tarroot}/${prefix}${user}/homedir/popaccts" );
system( "rm", "-rf", "${tarroot}/${prefix}${user}/homedir/Maildir" );

print "dXm Copying cpuser file.......";
open( CPU, ">${tarroot}/${prefix}${user}/cp/${user}" );
print CPU "DNS=${lcdns}\n";
open( LIMITS, "$truehomedir/.limits" );
while (<LIMITS>) {
    if (/^MySQL[^\=]*=(\d+)/i)     { print CPU "MAXSQL=$1\n"; }
    if (/^Bandwidth[^\=]*=(\d+)/i) { my $bwlimit = ( $1 * 1024 * 1024 ); print CPU "BWLIMIT=$bwlimit\n"; }
    if (/^Email Add[^\=]*=(\d+)/i) { print CPU "MAXPOP=$1\n"; }

    #        if (/^Subdom[^\=]*=(\d+)/i) { print CPU "MAXSUB=$1\n"; }
    if (/^FTP[^\=]*=(\d+)/i)     { print CPU "MAXFTP=$1\n"; }
    if (/^Cration[^\=]*=(\d+)/i) { print CPU "STARTDATE=$1\n"; }

    #        if (/^Reseller Domains[^\=]*=(\d+)/i) { print CPU "MAXADDON=$1\n"; }
}
close(LIMITS);
close(CPU);
print "Done\n";

print "dXm Getting quota info...";

my $quota = `quota -v ${user}`;
my @QUOTA = split( /\n/, $quota );
my $USED  = 0;
my $LIMIT = 0;

foreach my $line (@QUOTA) {
    $line =~ s/^\s*//g;
    if ( $line =~ /^\// ) {
        $line =~ /^(\S+)\s*(\d+)\s*(\d+)/;
        my $dsk = $1;
        if ( getmnt($dsk) =~ /backup/ ) {
            next;
        }
        $USED += $2;
        if ( $LIMIT eq '' || $LIMIT == 0 ) { $LIMIT = $3; }
    }
}

open( QUOTA, ">${tarroot}/${prefix}${user}/quota" );
$LIMIT = ( $LIMIT / 1024 );
print QUOTA "$LIMIT\n";
close(QUOTA);
print "Done\n";

print "dXm Copying password.......";
open( SH, ">${tarroot}/${prefix}${user}/shadow" );
open( S,  "/etc/shadow" );
my $pass;
while (<S>) {
    my ( $muser, $passwd, undef ) = split( /:/, $_, 3 );
    if ( $user eq $muser ) {
        $pass = $passwd;
        last;
    }
}
close(S);
print SH "$pass";
close(SH);
print "Done\n";

chdir("${tarroot}");
print "dXm Creating Archive ....";
if ($isbackup) {
    system( "tar", "pczf", "${prefix}${user}.tar.gz", "${prefix}${user}" );
}
else {
    if ( my $pid = fork() ) {
        my $dotcount = 5;
        while ( waitpid( $pid, 1 ) != -1 ) {
            if ( $dotcount % 5 == 0 ) {
                print ".........\n";
            }
            sleep(1);
            $dotcount++;
        }
    }
    else {
        system( "tar", "pczf", "${prefix}${user}.tar.gz", "${prefix}${user}" );
        exit();
    }
}
if ( -d "${tarroot}/${prefix}${user}" && !-l "${tarroot}/${prefix}${user}" ) {
    system( "rm", "-rf", "${tarroot}/${prefix}${user}" );
}
print "Done\n";
print "pkgacctfile is: $prefix$user.tar.gz\n";

my $md5sum; 
if ( $system =~ /freebsd/i ) {
    chomp( $md5sum = `md5 -r ${tarroot}/${prefix}${user}.tar.gz` );
}
else {
    chomp( $md5sum = `md5sum ${tarroot}/${prefix}${user}.tar.gz` );
}
$md5sum =~ /^(\S+)[\s|\t]*/;
$md5sum = $1;

print "md5sum is: $md5sum\n";

sub listsubdomains {
    my ($domain) = @_;
    my (@SD);
    my ($httpconf) = "/usr/local/apache/conf/vhosts.conf";
    my ($d);

    open( HTTPCONF, $httpconf );
    while (<HTTPCONF>) {
        if (/servername\s*(\S+)\.${domain}$/i) {
            if ( $1 !~ /^www$/i ) {
                $d = $1;
                $d =~ s/^www//g;
                $d =~ s/^\.//g;

                next if ( $d eq "" || $d eq "." );
                push( @SD, "${d}" );
            }
        }
    }
    close(HTTPCONF);
    return (@SD);
}

sub getmnt {
    my ($dsk) = @_;

    open( MTAB, "/etc/mtab" );
    while (<MTAB>) {
        if (/^${dsk}\s(\S+)/) {
            return $1;
        }
    }
    close(MTAB);
    return "";
}

