Skip to content

Instantly share code, notes, and snippets.

@mkasa
Created April 18, 2013 12:04
Show Gist options
  • Save mkasa/5412215 to your computer and use it in GitHub Desktop.
Save mkasa/5412215 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
use strict;
use Getopt::Long;
use File::Find;
my $debug = 0;
GetOptions(
'debug' => \$debug
);
my $flag_show_usage = 0;
my $indirname = shift;
my $outdirname = shift;
$flag_show_usage = 1 unless(defined $outdirname);
$flag_show_usage = 1 unless(defined $indirname);
if($flag_show_usage) {
print STDERR "usage: bmf2eml <directory to scan> <directory to output eml files>\n";
exit 1;
}
sub write_out
{
my ($mes_id, $date_str, $emails) = @_;
my $file_name;
if(!defined $mes_id) {
if(!defined $date_str) {
if(@$emails == 0) {
} else {
print "ERROR: no message id & date_str\n";
}
return;
} else {
$file_name = $date_str;
}
} else {
$file_name = $mes_id;
}
$file_name =~ s|:|-|g;
$file_name =~ s|[<>\\/\$;\x1b]||g;
$file_name =~ s|\R||g;
$file_name = $outdirname . "/" . $file_name . ".eml";
print "FN: $file_name\n" if($debug);
my $ofh;
unless(open $ofh, ">", $file_name) {
print "FN: $file_name\n";
die "Cannot open '$file_name'";
}
for(@$emails) {
print $ofh "$_\r\n";
}
close $ofh;
}
sub scan_wanted
{
my $f = $_;
if($f =~ m|\.bmf$|) {
# print "$File::Find::name searching ...\n";
my $fh;
open $fh, "<", $f or die;
my $count = 0;
my $message_id = undef;
my $date_str = undef;
my @mails = ();
while(<$fh>) {
chomp; chop if(/\r$/);
if(m|^\.$|) {
$count++;
write_out($message_id, $date_str, \@mails);
$message_id = undef;
$date_str = undef;
@mails = ();
} else {
if(m|^Message-ID:\s*<([\w\d\.\-_]+\@[\w\d\.\-_]+)>|i) {
$message_id = $1;
# print "$message_id\n";
} elsif(m|^Date:\s*(.*)$|i) {
$date_str = $1;
}
push(@mails, $_);
}
}
write_out($message_id, $date_str, \@mails);
print "$File::Find::name\t${count} e-mails\n";
close $fh;
}
}
unless(-x $indirname) {
print STDERR "ERROR: The input directory '$indirname' does not exist\n";
exit 1;
}
unless(-x $outdirname) {
print STDERR "ERROR: The output directory '$outdirname' does not exist\n";
exit 1;
}
finddepth(\&scan_wanted, $indirname);
=pod
=head1 NAME
bmf2eml - Convert bmf (Becky mail format) files to eml (e-mail) files.
=head1 SYNOPSYS
Convert all bmf files in a directory and its subdirectories (recursively searched):
B<bmf2eml> E<lt>input directoryE<gt> E<lt>output directoryE<gt>
=head1 DESCRIPTION
B<bmf2eml> converts all bmf files into eml files. Every message in a bmf file is
individually converted to an eml file. The file name of the eml file becomes the
Message ID of the original e-mail. In the case that Message ID was not available
(e.g., e-mails in Draft/Sent folders), the file name becomes the date of the message.
None of those are available, messages are discarded, but the author has not seen
any such cases with the author's 10,000+ e-mails.
=head1 NOTE
B<bmf2eml> does not consider security at all. For example, a malformed message ID
in an e-mail would destroy your computer, but B<bmf2eml> does not check it at all.
At a minimum, you should turn on anti-virus software to avoid potential disasters
caused by malformed e-mails.
=cut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment