#!/usr/local/bin/perl # Author: Kevin P. Inscoe . # File: ns42mozilla.pl # Date of creation: December, 28, 2002. # Warranty: None expressed or implied. # License: The Open Software License. V1.1 http://www.opensource.org/licenses/osl.php # # OSI Certified Open Source Software. http://www.opensource.org/licenses/ # # Prerequisites: Perl 5.004 (minimum). # The purpose of this program is # Requirements require 5.004; use strict; use Getopt::Long; use File::Find; use Digest::MD5; use File::Copy; #Turn off Perl buffering $| = 1; # Globals use vars qw($opt_V $opt_h $opt_d $opt_r $hostname $runtimedir); $main::dbg = 0; # Locals my $revision="1.0"; my $progname = "ns4mail2mozilla.pl"; my $pusage = "Usage: $progname\n"; my $copyright = "This software come with ABSOLUTELY NO WARRANTY.\nLicensed under the Open Software License V1.1.\nRefer to http://www.opensource.org/licenses/osl.php"; $pusage = $pusage . " " . $progname . " (-h|--help)\n"; $pusage = $pusage . " " . $progname . " (-V|--version)\n"; $pusage = $pusage . " " . $progname . " (-d|--debug)\n"; $pusage = $pusage . " " . $progname . " (-r|--rules) \n"; sub create_folders (); sub create_rules; sub make_folder (); sub copy_file; sub comp_file; my $ns4dir = "\\Program Files\\Netscape\\Users\\default"; my $MozDir = "\\windows\\Application Data\\Mozilla\\Profiles\\kinscoe\\7f64keo9.slt"; #$ns4dir = quotemeta $ns4dir; #$MozDir = quotemeta $MozDir; my $ns4MailDir = $ns4dir . "\\mail"; my $MozMailDir = $MozDir . "\\Mail\\Local Folders"; my $ns4Rules = $ns4dir . "\\mail\\rules.dat"; # Mozilla 1.3 has a new filter rules file name when written out # http://bugzilla.mozilla.org/show_bug.cgi?id=168553 # http://www.mozilla.org/mailnews/arch/filters/ #my $MozRules = $MozDir . "\\Mail\\pop.earthlink.net\\msgFilterRules.dat"; my $MozRules = $MozDir . "\\Mail\\pop.earthlink.net\\rules.dat"; # check args Getopt::Long::Configure('bundling', 'no_ignore_case'); GetOptions ("V|version" => \$opt_V, "h|help" => \$opt_h, "d|debug" => \$opt_d, "r|rules" => \$opt_r, # "<>" => \&bad_argument(), ); if ($opt_h) { print $pusage; print "\n$copyright\n"; print "\n"; exit 0; } if ($opt_V) { print "$progname: Version $revision\n\n"; print $pusage; print "\n$copyright\n"; print "\n"; exit 0; } if ($opt_d) { print "$progname: Version $revision\n\n"; print "debug: ON\n"; $main::dbg = 1; } # Main # First create the mail folders under Mozilla and migrate the mail... if (!$opt_r) { print "Migrating mail...\n"; create_folders; } # Now create the new mail rules print "Creating mail rules...\n"; create_rules ($ns4Rules, $MozRules); # Subs # A bad arguement was passed on the command line sub bad_argument () { print "Unrecognized option\n\n"; print $pusage; print "\n$copyright\n"; print "\n"; exit 1; } # Create Mozilla folders sub create_folders () { print "Processing $ns4MailDir...\n"; find(\&make_folder, $ns4MailDir); } # Make a folder in Mozilla sub make_folder () { my $source = $File::Find::name; # Match the hierarchy my $file = $_; my $dest = $source; # replace $ns4dir with $MozDir... my $pos = 0; substr($dest, $pos, length($ns4MailDir), $MozMailDir) while ($pos = index($dest, $ns4MailDir, $pos)) > -1; # if running this under DOS... $dest =~ s/\//\\/g; $source =~ s/\//\\/g; # Change "Archived Mail" to "Archive Mail" $dest =~ s/Archived Mail/Archive Mail/g; # If a directory make it over on the Mozilla side my $isdir = 0; -d and $isdir = 1; if ( $isdir == 1) { print "Creating directory $dest...\n" and mkdir $dest; return; } # return if a ".snm" file since the indices are different in Mozilla # and we will rebuild them there # Also don't copy Template, Trash or *.dat -f and /.snm$/ and return; -f and /^Template/ and return; -f and /^Trash/ and return; -f and /.dat$/ and return; -f and /.tmp$/ and return; -f and /mailfilt.log/ and return; # If this is directory "." (the source directory) don't copy either if ( $source eq $ns4MailDir ) { return; } # Ok if we got this far it's a mbox file so copy it over print "Copying $source\n\t to $dest...\n"; # copy the file copy_file ($source, $dest); return; } # Create mail rules sub create_rules () { my ($src, $dst) = @_; my $count = 0; my $blah = 0; open(SRC, "<$src") or die "Can't open '$src' for input: $!"; open(DST, ">$dst") or die "Can't open '$dst' for output: $!"; while () { chomp; # Before #version="6" #logging="yes" #name="*WX headsup" #enabled="yes" #description="" #type="1" #action="Watch thread" #condition=" AND (subject,contains,MESO:) AND (body,contains,FL )" # After # version="8" #logging="yes" #name="*WX headsup" #enabled="yes" #type="1" #action="Mark flagged" #condition="AND (subject,contains,MESO:) AND (body,contains,FL)" # Change version="6" to version="8" if ( m/version="6"/ ) { $_ = "version=\"8\"\n"; } if ( m/name=/ ) { if ( $main::dbg ) { print "debug: $_\n"; } } if ( m/action=/ ) { if ( $main::dbg ) { print "debug: $_\n"; } } # Convert obsolete actions... if ( m/action="Watch thread"/ ) { if ( $main::dbg ) { $_ = "action=\"Mark flagged\""; } } if ( m/action="Ignore thread"/ ) { if ( $main::dbg ) { $_ = "action=\"Delete\""; } } # Correct actionValue= if ( m/actionValue=/ ) { if ( $main::dbg ) { print "debug: $_\n"; } my $tmp = substr($_,13); # append in "mailbox://nobody@Local%20Folders/" and replace spaces with "%20" my $line = "actionValue=\"mailbox://nobody\@Local%20Folders/"; $line = $line . $tmp; $line =~ s/ /%20/g; # remove ".sbd" $line =~ s/.sbd//g; $_ = $line; if ( $main::dbg ) { print "debug: (new) $_\n"; } $count++; } # Change "Archived Mail" to "Archive Mail" $_ =~ s/Archived%20Mail/Archive%20Mail/g; if ( m/description=/ ) { $blah++; } else { print DST "$_\n"; } } print "$count rules converted\n"; return; } # Copy the mail file sub copy_file { my ($src, $dst) = @_; # Copy source to destination... copy($src,$dst); # Now compare the copied file to make sure it copied ok comp_file ($src, $dst); return; } # Verify the copied file sub comp_file { my ($src, $dst) = @_; open(SRC, "<$src") or die "Can't open '$src' for comparison: $!"; binmode(SRC); my $md5 = Digest::MD5->new; while () { $md5->add($_); } close(SRC); my $srcmd5 = $md5->b64digest; open(DST, "<$dst") or die "Can't open '$dst' for comparison: $!"; binmode(DST); $md5 = Digest::MD5->new; while () { $md5->add($_); } close(DST); my $dstmd5 = $md5->b64digest; if ( $main::dbg ) { print "\nMD5: $dst==> SRC=$srcmd5 DST=$dstmd5\n\n"; } if ($dstmd5 ne $srcmd5) { print "ERROR!: CHECKSUMS DO NOT MATCH - $dst\n\n"; } }