#!/usr/bin/perl
# cpanel - autofixer/clean_user_cpbackup-excludes 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, '/usr/local/cpanel'; }

use strict;
use warnings;
require IO::Handle;
require Cpanel::PwCache;
require Cpanel::Config::Users;
require Cpanel::AccessIds::SetUids;

my %dead_excludes = map { $_ => 1 } qw( core. .MirrorSearch .cpcpan .wysiwygPro_ access-logs .cpan .cpanel/datastore );

Cpanel::PwCache::init_passwdless_pwcache();

my @USERS = Cpanel::Config::Users::getcpusers();
foreach my $cpuser (@USERS) {
    my ( $useruid, $usergid, $homedir ) = ( Cpanel::PwCache::getpwnam($cpuser) )[ 2, 3, 7 ];
    if ( !$useruid || !$usergid || !$homedir ) {
        warn "Skipping invalid user $cpuser";
        next;
    }
    next if ( !-e $homedir . '/cpbackup-exclude.conf' || -z _ );
    my $begin_mtime = ( stat(_) )[9];

    if ( my $pid = fork() ) {
        waitpid( $pid, 0 );
    }
    else {
        Cpanel::AccessIds::SetUids::setuids( $useruid, $usergid ) || die "Could not setuid to uid $cpuser";
        my $safe_file = $homedir . '/cpbackup-exclude.conf';
        $safe_file =~ m/(.*)/;
        $safe_file = $1;    #untaint

        my %excludes;
        my $updated    = 0;
        my $exclude_fh = IO::Handle->new();
        if ( open $exclude_fh, '+<', $safe_file ) {
            while ( my $line = readline $exclude_fh ) {
                chomp $line;
                next if $line =~ m/\A\s*\z/s;
                next if $line =~ m/\A\s*#/s;
                if ( exists $dead_excludes{$line} ) {
                    $updated++;
                    next;
                }
                $excludes{$line} = 1;
            }
        }
        else {
            die "Failed to read $safe_file: $!";
        }

        if ($updated) {
            seek( $exclude_fh, 0, 0 );
            truncate( $exclude_fh, tell($exclude_fh) );

            # Write updated values
            foreach my $exclude ( sort keys %excludes ) {
                print {$exclude_fh} $exclude . "\n";
            }
        }
        close $exclude_fh;

        if ( $begin_mtime < ( stat( $homedir . '/cpbackup-exclude.conf' ) )[9] ) {
            print "Updated exclude file $homedir/cpbackup-exclude.conf\n";
        }

        exit;
    }
}
