#!/usr/bin/perl
# cpanel10 - synccpaddonswithsqlhost              Copyright(c) 2005 cPanel, Inc.
#                                                           All rights Reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cpanel license. Unauthorized copying is prohibited

use strict;
use warnings;
use Carp;
use File::Spec;
use Storable;
use lib '/usr/local/cpanel/cpaddons';

# my $mypass = get_root_mysql_pass();
my $myhost = get_root_mysql_host();

print "Syncing cPAddons installations with current MySQL host setting!\n\n";

DOUSER:
for my $user (@{ get_all_users_or_arg_ref() }) {
    print "Processing $user...\n";
    my $home = (getpwnam( $user ))[7];
    if(!defined $home) {
        carp "Could not determine home for $user";
        next DOUSER;
    }
    chdir $home or croak "Could not go into $home for $user: $!";
    
    my @cpaddons;
    if(opendir my $cpaddons_dh, '.cpaddons/') { 
        @cpaddons = grep { /\:\:/ } readdir $cpaddons_dh;
        closedir $cpaddons_dh;
    }
    else {
        carp "Can not read .cpaddons/ for $user, skipping: $!";
        next DOUSER;
    }
    
    my $cpaddons_processed = 0;

    CPADDON_INSTALLATION:
    for my $aod (@cpaddons) {
        print "\tChecking $aod...\n";
        my $install_hashref = retrieve ".cpaddons/$aod"
            or croak "Could not read $aod: $!";

        my $mod = $aod;
        $mod =~ s{\.\d+$}{};
        eval "use $mod;";
        if($@) {
            carp "Skipping $aod, Could not get $mod info (is $mod installed?): $!";
            next CPADDON_INSTALLATION;
        }
        else {
            no strict 'refs';
            my $info_hr = ${"$mod\:\:meta_info"};
            use strict 'refs';
            
            for my $db (@{ $info_hr->{'mysql'} }) {

                my $current_setting = $install_hashref->{"mysql.$db.sqlhost"} || '';
                next CPADDON_INSTALLATION if $myhost eq $current_setting
                                          || (!$myhost || !$current_setting);
                print "\t\tDifference detected, syncing...\n";
            
                for my $conf(@{ $info_hr->{'config_files'} }) {
                    my $path = File::Spec->catdir($install_hashref->{'installdir'}, $conf);
                    print "\t\t\tProcessing $path...";
                    system 'perl', '-pi', '-e', qq('s{$current_setting}{$myhost}g;'), $path;
                    print "Done!\n";
                }
                $install_hashref->{"mysql.$db.sqlhost"}     = $myhost;
                $install_hashref->{'mysql'}{$db}{'sqlhost'} = $myhost;
                store $install_hashref, ".cpaddons/$aod"
                    or carp "Could not save $aod: $!";
                print "\t\t$aod is done\n";
                $cpaddons_processed++;
            }
        }
    }

    if($cpaddons_processed) {
        my $s = $cpaddons_processed == 1 ? '' : 's';
        print "$user had $cpaddons_processed cpaddon$s synced\n";
    }
    else {
        print "$user had no cpaddons needing their mysql host synced\n";
    }
    print "$user Done!\n\n";
}

#############################################
#### put in module & use that module above ##
#### use Carp;                             ##
#############################################

sub get_root_mysql_pass {
    my $mypass = '';
    open my $mycnf_fh, '<', '/root/.my.cnf'
        or croak "Set MySQL root passwd: $!";
    while(<$mycnf_fh>) {
        if($_ =~ m/pass\s*\=/) {
            ($mypass) = $_ =~ m/pass\s*\=\s*\"?([^\"\s]+)\"?/;
            last;
        }
    }
    close $mycnf_fh;
    return $mypass;
}

sub get_root_mysql_host {
    my $mypass = '';
    open my $mycnf_fh, '<', '/root/.my.cnf'
        or croak "Set MySQL root passwd: $!";
    while(<$mycnf_fh>) {
        if($_ =~ m/host\s*\=/) {
            ($myhost) = $_ =~ m/host\s*\=\s*\"?([^\"\s]+)\"?/;
            last;
        }
    }
    close $mycnf_fh;
    return $myhost || 'localhost';
}

sub get_all_users_or_arg_ref {
    my $arg_location = shift || 0;
    my $user_to_run = defined $ARGV[$arg_location]
                      && $ARGV[$arg_location]
                      ? $ARGV[$arg_location] : '';
    my $user_lookup_ref = get_user_lookup_ref();

    my @users_to_transform = keys %{ $user_lookup_ref };

    if($user_to_run) {
        if(exists $user_lookup_ref->{$user_to_run}) {
            @users_to_transform = ($user_to_run);
        }
        else {
            croak 'Unknown user';
        }
    }
    return \@users_to_transform;
}

sub get_user_lookup_ref {
    my $user_lookup = {};

    open my $TUD, '/etc/trueuserdomains' or die "trueuserdomains failed: $!";
    while( <$TUD> ) {
        my ($user) = $_ =~ m/\:\s+(\w+)/;
        $user_lookup->{ $user }++ if $user;
    }
    close $TUD;
    return $user_lookup;
}
