#!/usr/bin/perl

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

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

    ######################################################################
    #  Program name   mozillaToIMAP.pl                                   #
    #  Written by     Rick Sanders                                       #
    #  Date           21 Oct 2005                                        #
    #                                                                    #
    #  Description                                                       #
    #                                                                    #
    #  mozillaToIMAP.pl is used to copy Mozilla/Netscape messages        #
    #  to an IMAP server.  The script parses the Mozilla mailfiles       #
    #  into separate messages which are inserted into mailboxes of       #
    #  the same name on the IMAP server (creating the mailbox if it      #
    #  does not already exist).                                          #
    #                                                                    #
    #  Usage: mozillaToIMAP.pl -i host/username/password                 #
    #                                                                    #
    #  See the Usage() for available options.                            #
    #                                                                    #
    ######################################################################

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

push( @dirs, $mbxroot );
find( \&getMailboxes, @dirs );
$added=$failed=0;
foreach $mbx ( @mbxs ) {
    $msgs=$errors=0;
    $mbxs++;

    #  Build the IMAP mailbox name
    $imapmbx = $mbx;
    $imapmbx =~ s/$mbxroot//;
    $imapmbx =~ s/\.sbd//g;
    $imapmbx =~ s/^\///;
    &Log("Copying mailbox $imapmbx");

    @msgs = &readMbox( "$mbx" );
    foreach $msg ( @msgs ) {
       my $message;
       my $status;
       foreach $_ ( @$msg ) { 
          next if /^From -/;
          if ( /^Date: (.+)/ ) {
             $date = $1 unless $date;
          }
          if ( /^X-Mozilla-Status: (.+)/i ) {
             #  Grab the message status and figure out which
             #  bits are set.  See http://www,eyrich-net.org/mozilla/X-Mozilla-Status.html
             #  Set the corresponding IMAP message flags (eg SEEN, DELETED, etc).
             #  The format is \FLAG1 \FLAG2 etc.  For example: \SEEN \DELETED.
          }
          $message .= $_; 
       }

       if ( &insertMsg($imapmbx, \$message, $flags, $date, 'IMAP') ) {
          $added++;
          &Log("Added msg") if $debug;
       } else {
          $failed++;
          &Log("Failed to add msg") if $debug;
       }
    }
}

&logout( 'IMAP' );

&Log("\n\nSummary:\n");
&Log("   Mailboxes  $mbxs");
&Log("   Total Msgs $added");
&Log("   Failed Msgs $failed");
i&Log("Done");
exit;


sub init {

   if ( !getopts('m:L:i:dI') ) {
      &usage();
   }

   $mbxroot  = $opt_m;
   $logfile  = $opt_L;
   $debug    = 1 if $opt_d;
   $showIMAP = 1 if $opt_I;
   ($imapHost,$imapUser,$imapPwd) = split(/\//, $opt_i);
   IMAP::Utils::init();
   if ( $logfile ) {
	openLog($logfile);
   }
   Log("Starting");

}



sub usage {

   print "Usage: iu-mozillatoimap\n";
   print "    -m <root location of mailfiles>\n";
   print "    -i <server/username/password>\n";
   print "    [-L <logfile>]\n";
   print "    [-d debug]\n";
   print "    [-I log IMAP protocol exchanges]\n";

}

#
#  readMbox
#
#  Read a Mozilla mailbox and get the messages in it
#

sub readMbox {

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

    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;
}

#
#  getMailboxes
#
#  Get a list of the Mozilla mailboxes and populate @mbxs with the
#  mailbox filepath
#

sub getMailboxes {

my $fn;

   return if not -f;
   $fn = $File::Find::name;

   unless ( $fn =~ /\.sbd$|\.msf|\.dat|\.html/ ) {
        push( @mbxs, $fn );
   }
   
} 

