#!/usr/bin/perl -w

####################################################################################
#
#  This script does the following:
#
#  1)asks for domain name, login and password
#  2)connects to CommuniGate Server on the given domain
#  3)for each user in the given domain, it
#  4a)Enables WebSite access if it was off.
#  4b)Checks "Add Web Banner" parameter and turns it to "YES" if it was off.
#  4c)Increases the allowed number of Web files if it was less than 10.
#  4d)Increases the allowed space for web files if it was less than 100K.
#  5)disconnects.
#
#################################################################################### 

use CLI;


# The list of parameters to change
my $paramsToSet = {
  AddWebBanner => 'YES',         # force the web banner
};

# The list of parameters to increase
my $paramsToIncrease = {
  MaxWebFiles => 10,             # new limit for the number of web files
  MaxWebSize => "100K",          # new limit for maximun web storage
};


print "Domain: ";         # Print the domain prompt
my $Domain = <STDIN>;     # Read the domain name from standard input
chomp $Domain;            # Remove \n if present

# You may need to redefine the following variable if you're connecting not to
# the main domain. IP address is OK.
$CGServerAddress = $Domain;

print "Login (Enter for \"Postmaster\@$Domain\"): ";
my $Login = <STDIN>;
chomp $Login;
if ($Login eq '') { $Login = "Postmaster\@$Domain"; }

print "Password: ";
my $Password = <STDIN>;
chomp $Password;

# Open TCP connection to given address port 106 (PWD, or CGPro CLI).
# Submit username and password. If login fail, the program will stop.
my $cli = new CGP::CLI( { PeerAddr => $CGServerAddress,
                          PeerPort => 106,
                          login    => $Login,
                          password => $Password } )
   || die "Can't login to CGPro: ".$CGP::ERR_STRING."\n";

my $oldUserData;
my $newUserData;                 #the array for new settings
my $needUpdate = 0;              #flag if we need to update the user


# Read the list of accounts.
# The list is a hash with key="user name" and value="mailbox type".
my $accountList = $cli->ListAccounts($Domain);

# If the list is empty, stop with the error message. 
die "\nError " . $cli->getErrMessage . "(".$cli->getErrCode.
    ") fetching accounts list\n"
    unless ($accountList);

my $UserName;
my ($count,$cntUpdated,$cntFailed)=(0,0,0);

# Process each list entry  
foreach $UserName (keys %$accountList) {
  # Get the list of account parameters. The list is a hash,
  # the key is a parameter name and value is the parameter's value.

  print "Processing \"$UserName\@$Domain\"\n";

  $oldUserData = $cli->GetAccount("$UserName\@$Domain")
                 || die "Unable to get data for $UserName: "."(" .
                         $cli->getErrMessage . ")\n";

  $needUpdate = 0;
  delete @$newUserData{'AccessModes'};  #remove the data from previous account

  # Check if WebSite is enabled and turn it on if necessary
  my $accessModes=@$oldUserData{'AccessModes'};
  unless($accessModes eq 'All') {  #if(!(accesModes=="All"))
    my $needUpdateAccessMode=1;
    foreach(@$accessModes) {       #for $_ = accessModes[index]
      if(/^WebSite/) {             #if($_ starts with "WebSite")
        $needUpdateAccessMode=0;
        last;                      #break the 'foreach' loop
      }
    }
    if($needUpdateAccessMode) {
      print "Enabling WebSite access\n";
      push(@$accessModes,'WebSite');               #add "WebSite" to accessModes
      @$newUserData{'AccessModes'} = $accessModes; #include accessModes to data to update
      $needUpdate = 1;
    }
  }

  foreach (keys %$paramsToSet) {
    SetParameter($_,@$paramsToSet{$_});
  }

  foreach (keys %$paramsToIncrease) {
    IncreaseParameter($_,@$paramsToIncrease{$_});
  }

  if($needUpdate) {
    print "updating...\n";
    if($cli->UpdateAccount("$UserName\@$Domain",$newUserData)) {
      ++$cntUpdated;
    } else {
      ++$cntFailed;
      print "Error ".$cli->getErrMessage." (".$cli->getErrCode.")\n";
    }
  } else {
    print "no need to update $UserName\n";
  }
  ++$count;
}

print "\nTotal: $count, Udated: $cntUpdated, Failed: $cntFailed\n";  # Print the total/updated number of users .
$cli->Logout;                                  #close the connection to CGPro


# SetParameter(theParameterName,newValue)
sub SetParameter {
  my $theKey = $_[0];
  my $newValue = $_[1];
  my $oldValue = @$oldUserData{$theKey};
  if(!defined($oldValue) || $oldValue ne $newValue) {
    @$newUserData{$theKey}=$newValue;
    print "Setting $theKey to $newValue\n";
    $needUpdate=1;
  }
}


# IncreaseParameter(theParameterName,newValue)
sub IncreaseParameter { 
  my $theKey = $_[0];
  my $newValue = $_[1];
  my $oldValue = @$oldUserData{$theKey};

  delete @$newUserData{$theKey};
  unless(defined($oldValue)) { $oldValue=0; }
  if(ExpandNum($newValue) > ExpandNum($oldValue)) {
    @$newUserData{$theKey}=$newValue;
    print "Increasing $theKey from $oldValue to $newValue\n";
    $needUpdate=1;
  }
}

#ExpandNum(number). Expands kilobytes and megabytes into bytes.
sub ExpandNum {            
  my $num=$_[0];
  if($num =~/unlimited/i) {	#if the number is 'unlimited'
    return hex('7FFFFFFF'); #then expand it to the lagest possible number
  } else {
    $num =~ /(\d+)([KM]?)/i; #store digits into $1 and 'K' or 'M' into $2
    my $value=$1;
    my $suffix=$2;
    if($suffix =~ /^K/i) {$value*=1024;}
    elsif($suffix =~ /^M/i) {$value *= 1024 * 1024;}
    return $value;
  }
}
