#!/usr/bin/env perl # # ./undup-mbox, but with a proper mailbox processing library # # $Id$ use strict; use warnings; use Getopt::Std; use Mail::Box::Manager; my %opt; getopts( 'dhilB:H:o:ux:', \%opt ); $opt{h} and HELP_MESSAGE(); sub HELP_MESSAGE { print STDERR < create_filter('H'), 'B' => create_filter('B') ); my $mgr = new Mail::Box::Manager; if ( $opt{d} ) { $mgr->defaultTrace('DEBUG'); } my $out; if ( defined $outbox ) { $out = $mgr->open( folder => $outbox, access => 'rw', create => 1 ) or die "cannot open/create output mbox '$outbox'\n"; # access should be w except for a bug in Mail::Box::File, see # https://rt.cpan.org/Ticket/Display.html?id=44439 } my %uid; # the IDs of messages found, if -u is specified my %xid; # the IDs of messages to exclude, if -x is specified if ( $opt{x} ) { # the argument is the mailbox to *subtract* from the # other messages my $xbox = $opt{x}; my $xin = $mgr->open( folder => $xbox, access => 'r', keep_dups => 0 ) or die "cannot open input mbox '$xbox'\n"; foreach my $msg ( $xin->messages ) { ++$xid{ $msg->messageId }; } $mgr->close( $xin, write => 'NEVER' ); } @ARGV or die "specify at least one mailbox file as argument\n"; my %argv_matches; $opt{l} and $| = 1; # flush the output foreach my $inbox (@ARGV) { my $in = $mgr->open( folder => $inbox, access => 'r', lock_type => 'NONE', keep_dups => !$opt{u} ) or die "cannot open input mbox '$inbox'\n"; foreach my $msg ( $in->messages ) { next if defined $xid{ $msg->messageId }; if ( $opt{u} ) { # de-duplicate even between different input folders next if defined $uid{ $msg->messageId }; ++$uid{ $msg->messageId }; } if ( $passes{'H'}( $msg->head() ) && $passes{'B'}( $msg->body() ) ) { if ( $opt{l} ) { $argv_matches{$inbox}++ or print "$inbox\n"; # print its name on the first match } elsif ( defined $out ) { $mgr->copyMessage( $out, $msg ); } else { $msg->write; } } } $mgr->close( $in, write => 'NEVER' ); } if ( defined $out ) { $mgr->close( $out, write => 'ALWAYS' ) or die "could not write outbox '$outbox': $!\n"; }