#!/usr/sup/gnu/bin/perl -w use strict; use Carp; sub print_usage_and_die { die "Usage: $0 [ --mh-directory= ] " . "[ --ns-directory=] " . " [ --verbose ]\n"; } # Default versions of the MH mail directory and the Netscape mail # directory. my $mh_dir = "$ENV{'HOME'}/Mail"; my $ns_dir = "$ENV{'HOME'}/nsmail"; my $verbose = 0; # Standard sequence to read options my $arg; OPTIONS: while (defined ($arg = shift)) { if (/^--/) { if (/^--mh-directory=(.*)$/) { $mh_dir = $1; } elsif (/^--ns-directory=(.*)$/) { $ns_dir = $1; } elsif (/^--verbose$/) { $verbose = 1; # Be verbose } else { print_usage_and_die; } } else { last OPTIONS; } } unshift(@ARGV, $arg) # Put back the unused argument. if defined $arg; print_usage_and_die # There shouldn't be any arguments left if (@ARGV > 0); sub move_mail ($$); # Forward declaration of move_mail # move_mail is a recursive routine that accespts two arguments: a path # to a MH directory ('$mhdir') and a path to a Netscape directory # ('$nsdir'). The routine will # # 1) take the messages in $mhdir and concatenate them into a mailbox # file $mbfile with the same name as $mh_dir. The mailbox file # is placed in $nsdir. # # 2) Create a directory in $nsdir with the name $mhdir.sbd. # # 3) For each directory $subdir in $mhdir, Call itself recursively # with $mhdir/$subdir and $nsdir/$mhdir.sbd as arguments. sub move_mail ($$) { my @mh_path = split('/',$_[0]); my @ns_path = split('/',$_[1]); my $ns_base = $ns_path[$#ns_path]; my $ns_dir = join('/',@ns_path[0..$#ns_path-1]); my $mh_base = $mh_path[$#mh_path]; my $mh_dir = join('/',@mh_path[0..$#mh_path-1]); croak "Usage: move_mail \n" unless @_ == 2 && defined $ns_base; # Create the directory and set the permissions correctly. if (-e $_[1] && ! -d $_[1]) { die "The file $_[1] exists and is not a directory!!\n"; } else { system("mkdir $_[1]"); chmod(0755, $_[1]); } # Read entries in the directory opendir(DIR,$_[0]) or die "cannot open $_[0]: $!"; my @entries = readdir(DIR); closedir(DIR); # Extract all folders and all mails. my @mails = sort { $a <=> $b } grep(/^\d+$/ && -f "$_[0]/$_", @entries); my @folders = grep { /^[\w\d]+$/ && -d "$_[0]/$_" } @entries; # If we have any mails at all, create a mailbox file to store the # messages in. if (@mails > 0) { open(OUT,">$ns_dir/$mh_base") or die "cannot open $ns_dir/$mh_base: $!"; # This is necessary for Netscape to understand the mailbox # file, strange. print OUT "\n\n"; chmod(0600, "$ns_dir/$mh_base"); print STDERR "Appending to $ns_dir/$mh_base\n" if $verbose; # Store the MH mails in the mailbox file. foreach my $mail (@mails) { print STDERR " $_[0]/$mail\n" if $verbose; # Skip mails with zero size next if -z "$_[0]/$mail"; open(FD,"$_[0]/$mail") or die "cannot open $_[0]/$mail: $!"; my $mail_text = ""; my @date = (); my $from = "-"; while () { $mail_text .= $_; # Fetch the date in the header for use when creating the # envelope. if (@date == 0 && /^Date:\s*(.*?)\s*$/) { @date = split(/,?\s+/,$1); } # Fetch a mail address from the From field, also for use in # the envelope. if ($from eq "-" && /^From:.*\<(\w+(?:\.\w+)*@\w+(?:\.\w+)*)\>.*/) { $from = $1; } } close(FD); # If we had a date and a from address, we can generate the # envelope. if (@date > 0 && $from) { print OUT "\n\nFrom $from @date[0,2,1,4,3]\n"; print OUT $mail_text; } else { # We can not generate an envelope, ignore the mail and print # an error message. print STDERR "'$_[0]/$mail' seems to be a corrupt mail.\n"; } } close(OUT); } foreach my $folder (@folders) { move_mail "$_[0]/$folder", "$_[1]/$folder.sbd"; } } move_mail($mh_dir, $ns_dir); __END__ =head1 NAME mh2ns - Program to convert MH mail hiearachy to Netscape folders =head1 SYNOPSIS mh2ns [ --mh-directory=I ] [ -ns-directory=I ] =head1 DESCRIPTION A small program that moves files stored as a MH directory tree into the format used by Netscape mailers. An MH directory tree consists of one directory per folder, with the messages as separate files. An Netscape directory tree consists of one directory per folder with subfolders, and one file containing all the messages of the folder. The messages are stored in standard mailbox format. For the envelope, the program uses the mail address stored in the From header of the message. The following options are available: =over 4 =item --ns-directory=I Use I as the root of the Netscape directory hierarchy when building the Netscape folders. =item --mh-directory=I Use I as the root of the MH directory hierarchy when moving MH mails. =item --verbose Be verbose, report every file moved and every directory created. =back =head1 COPYRIGHT Copyright (C) 1999 Matz Kindahl. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.