#!/usr/bin/perl

# $Header: /mhub4/sources/imap-tools/mbxIMAPsync.pl,v 1.1 2008/10/18 15:09:25 rick Exp $

use Socket;
use FileHandle;
use Fcntl;
use Getopt::Std;
use IMAP::Utils;

    ######################################################################
    #  Program name   mbxIMAPsync.pl                                     #
    #  Written by     Rick Sanders                                       #
    #  Date           12 Feb 2004                                        #
    #                                                                    #
    #  Description                                                       #
    #                                                                    #
    #  mbxIMAPsync is used to synchronize the contents of a Unix         #
    #  mailfiles with an IMAP mailbox.  The user supplies the location   #
    #  & name of the Unix mailbox (eg /var/mail/rfs) and the hostname,   #
    #  username, & password of the IMAP account along with the name      #
    #  of the IMAP mailbox.  For example:                                #
    #                                                                    #
    #  ./mbxIMAPsync.pl -f /var/mail/rfs -i imapsrv/rfs/mypass -m INBOX  #
    #                                                                    #
    #  mbxIMAPsync compares the messages in the mailfile with those in   #
    #  the IMAP mailbox by Message-Id and adds the ones in the mailfile  #
    #  which are not in the IMAP mailbox.  Then it looks for messages    #
    #  in the IMAP mailbox which are not in the mailfile and removes     #
    #  them from the IMAP mailbox.                                       #
    #                                                                    #
    #  See the Usage() for available options.                            #
    ######################################################################

    &init();

   &connectToHost($imapHost, 'IMAP');
   &login($imapUser,$imapPwd, 'IMAP');

   #  Get list of msgs in the mailfile by Message-Id

   $added=$purged=0;
   print STDOUT "Processing $mailfile\n";
   print STDOUT "Checking for messages to add\n";
   @msgs = &readMbox( $mailfile );
   foreach $msg ( @msgs ) {
       @msgid = grep( /^Message-ID:/i, @$msg );
       ($label,$msgid) = split(/:/, $msgid[0]);
       chomp $msgid;
       &trim( *msgid );
       $mailfileMsgs{"$msgid"} = '1';
       push( @sourceMsgs, $msgid );

       if ( !&findMsg( $msgid, $mbx, 'IMAP' ) ) {
          # print STDOUT "Need to add msgid >$msgid<\n";
          my $message;

          foreach $_ ( @$msg ) { chop $_; $message .= "$_\r\n"; }

          if ( &insertMsg('IMAP', $mbx, \$message, $flags, $date) ) {
             $added++;
             print STDOUT "   Added $msgid\n";
          }
       }
   }

   #  Remove any messages from the IMAP mailbox that no longer
   #  exist in the mailfile

   print STDOUT "Checking for messages to purge\n";
   &getMsgList( $mbx, \@imapMsgs, 'IMAP' );
   foreach $msgid ( @imapMsgs ) {
      if ( $mailfileMsgs{"$msgid"} eq '' ) {
         $msgnum = &findMsg( $msgid, $mbx, 'IMAP' );
         if ( &deleteMsg($msgnum, 'IMAP') ) {
            &Log("   Marked $msgid for deletion");
            print STDOUT "   Marked msgid $msgid for deletion\n";
            $deleted++;
         } 
      }
   }

   if ( $deleted ) {
      #  Need to purge the deleted messages
      $purged = &expungeMbx( $mbx, 'IMAP' );
   }

   &Log("Done");
   &Log("Added  $added messages to IMAP mailbox $mbx");
   &Log("Purged $purged messages from IMAP mailbox $mbx");

   print STDOUT "\nAdded  $added messages to IMAP mailbox $mbx\n";
   print STDOUT "Purged $purged messages from IMAP mailbox $mbx\n";

   exit;


sub init {

   if ( ! getopts('f:m:i:L:dx') ) {
      &usage();
      exit;
   }

   ($imapHost,$imapUser,$imapPwd) = split(/\//, $opt_i);
   $mailfile = $opt_f;
   $mbx      = $opt_m;
   $logfile  = $opt_L;
   $debug    = 1 if $opt_d;

   IMAP::Utils::init();
   if ( $logfile ) {
      openLog($logfile);
   }
   Log("\nThis is mbxIMAPsync\n");

   if ( !-e $mailfile ) {
      &Log("$mailfile does not exist");
      exit;
   }

}

sub usage {

   print "Usage: iu-mbximapsync\n";
   print "    -f <location of mailfiles>\n";
   print "    -i imapHost/imapUser/imapPassword\n";
   print "    -m <IMAP mailbox>\n";
   print "    [-L <logfile>]\n";
   print "    [-d debug]\n";

}

sub readMbox {

my $file  = shift;
my @mail  = ();
my $mail  = [];
my $blank = 1;
local *FH;
local $_;

    &Log("Reading the mailfile") if $debug;
    open(FH,"< $file") or die "Can't open $file";

    while(<FH>) {
        if($blank && /\AFrom .*\d{4}/) {
            push(@mail, $mail) if scalar(@{$mail});
            $mail = [ $_ ];
            $blank = 0;
        }
        else {
            $blank = m#\A\Z#o ? 1 : 0;
            push(@{$mail}, $_);
        }
    }

    push(@mail, $mail) if scalar(@{$mail});
    close(FH);

    return wantarray ? @mail : \@mail;
}
