#!/usr/bin/perl -w

#
# touchMailboxes.pl
#
# A script which walks through all mailboxes and forcing them to create indexes.
#
# Please mail your comments to support@communigatepro.ru
#



use strict;
use CLI;  #get one from communigatepro.ru/CGPerl


####  YOU SHOLD REDEFINE THESE VARIABLES !!!

my $CGServerAddress='127.0.0.1';  #IP or domain name;
my $Login='postmaster';
my $Password='pass';

my $InboxOnly=0; # change to 1 to touch INBOXes only 

#### end of the customizeable variables list


my $imap = new IO::Socket::INET(   PeerAddr => $CGServerAddress,
                                    PeerPort => 143
                                  ) 
   || die "*** Can't connect to CGPro via IMAP.\n";                                

$imap->autoflush(1);
my $responseLine = <$imap>;
#print "$responseLine\n";

print $imap "x LOGIN $Login $Password\015\012";
do {
  $responseLine = <$imap>;
}until($responseLine =~/^x /);
die "*** Can't login to CGPro IMAP: $responseLine.\n" unless($responseLine =~ /^x OK/);

my $cli = new CGP::CLI( { PeerAddr => $CGServerAddress,
			  isSSLTransport=>0,
                          PeerPort => 106,
                          login    => $Login,
                          password => $Password } )
   || die "*** Can't login to CGPro CLI: ".$CGP::ERR_STRING."\n";


# uncomment one of these:

#processAccount('user@company.com');
#processDomain($domain);
processAllDomains();
#processFile('accountList.txt');

print "Done\n";
$cli->Logout();
print $imap "x LOGOUT\015\012";
exit;

sub processFile {
  my ($fname)=@_;
  open(FILE,$fname) || die "can't open $fname: $!\n";
  while(<FILE>) {
    chomp;
    next if(/^#/);
    
    my ($account,$size)=split(/\t/);
    if(length($account)>3) {
      processAccount("$account");
    }
  }
  close(FILE);
}

sub processAllDomains {
  my $DomainList = $cli->ListDomains()
               || die "*** Can't get the domain list: ".$cli->getErrMessage.", quitting";
  foreach(@$DomainList) {
    processDomain($_);
  }
}         

sub processDomain {
  my $domain=$_[0];
  print "Domain: $domain\n";

  my $cookie="";
  do {
    my $data=$cli->ListDomainObjects($domain,5000,undef,'ACCOUNTS',$cookie);
    unless($data) {
      print "*** Can't get accounts for $domain: ".$cli->getErrMessage."\n";
      return;
    }
    $cookie=$data->[4];
    foreach(keys %{$data->[1]} ) {
      processAccount("$_\@$domain"); 
    }
  }while($cookie ne '');
 
}

sub processAccount {
  my $account=$_[0];
  print "Account: $account\n";

  if($InboxOnly) {
    processMailbox("$account/INBOX");
    return; 
  }
  
  my $mailboxesList=$cli->ListMailboxes(accountName=>$account);  
  unless($mailboxesList) {
    print "*** Can't list mailboxes for $account:".$cli->getErrMessage."\n";
    return;
  }
  foreach(keys %$mailboxesList) {
    my $data=@$mailboxesList{$_};
    if(ref $data eq 'ARRAY') {
      $data=@$data[0];
    }   
    if(ref $data eq 'HASH') {
      my $nMessages=@$data{'Messages'};
      $nMessages=$1 if($nMessages=~/(\d+)/);
      if(defined $nMessages && $nMessages==0) {
        # print "   skipping empty $account/$_\n";
        next;
      }
      processMailbox("$account/$_"); 
    }
  }  
}

sub processMailbox {  
  my $mailbox=$_[0];
  my $nMessages=0;
  print "  Mailbox: $mailbox\n";
  
  print $imap "x SELECT \"~$mailbox\"\015\012";
  do {
    $responseLine = <$imap>;
    if($responseLine =~ /^\* (\d*) EXISTS/) {
      $nMessages=$1;
    }
  }until($responseLine =~/^x /);
  unless($responseLine =~ /^x OK/) {
    print "*** Can't select $mailbox: $responseLine.\n";
    return;
  }
  if($nMessages==0) {
    print "   $mailbox is empty\n";
    return;
  }
 
    print $imap "c store 1 +FLAGS (\$Forwarded)\015\012";
    do {
      $responseLine = <$imap>;
    }until($responseLine =~/^c /);
    unless($responseLine =~ /^c OK/) {
      print "*** Can't store flag ~$mailbox: $responseLine.\n";
      return;
    }

    print $imap "c store 1 -FLAGS (\$Forwarded)\015\012";
    do {
      $responseLine = <$imap>;
    }until($responseLine =~/^c /);
    unless($responseLine =~ /^c OK/) {
      print "*** Can't clear flag ~$mailbox: $responseLine.\n";
      return;
    }

  
  
}


__END__
