#!/usr/bin/perl # 2003 Michael Fischer v. Mollard # # Durchsucht einen Folder IMAP Server nach Nachrichten mit doppelter Message_id # und markiert die überschüssigen als gelöscht. # Änderungen: # 08.09.2003 fvm Sucht jetzt nur noch in nicht als gelöscht markierten # Nachrichten nach Duplikaten # $Id: cyrus_search_dups.pl,v 1.5 2003/11/06 12:46:30 fvm Exp $ # Versionsbeschreibungen my ($nonsense2, $version) = split ' ',"\$Revision: 1.5 $$"; my ($nonsense1, $date1, $date2)=split ' ',"\$Date: 2003/11/06 12:46:30 $$"; my $date = join ' ', $date1, $date2; my $author="Michael Fischer v. Mollard"; my $mailto="fvm\@heise.de"; use Mail::IMAPClient; use Getopt::Std; use strict; # Konstanten my $IMAPSERVER='localhost'; my %arguments; my ($imap,$folderstructref,@dup_ids); sub usage(){ print <=0){ @dupid_splice = splice(@dup_ids, 0, $SPLICE_LENGTH); $imap->delete_message(@dupid_splice); } } sub search_dubs($){ my $folder = @_[0]; my ($hashref,@all_ids); my $SPLICE_LENGTH = 100; $imap->select($folder) or die "$folder nicht gefunden!\n"; @all_ids=$imap->search("NOT DELETED"); # Ich muss die Abfrage zerlegen, weil mich sonst bei zu großen # Anfragen der IMAP Server rauswirft (BYE word to long) while ($#all_ids>=0){ my @id_splice= splice(@all_ids,0,$SPLICE_LENGTH); $hashref = $imap->parse_headers(\@id_splice ,"Date","Message-ID","Subject","To"); # Hash aufbauen, das die Message ID als schlüssel hat und als Wert # ein Array von Ergebnissen der parse_headers Funktion. Wenn es nur ein # Element gibt, ist die Nachricht eindeutig. foreach my $uid (@id_splice){ if ($folderstructref->{$hashref->{$uid}->{'Message-ID'}->[0]}){ # Falls ein kapputter Client die Message-ID recycled, sollte wenigstens # das Datum anders sein if ($hashref->{$uid}->{'Date'}->[0] eq $folderstructref->{$hashref->{$uid}->{'Message-ID'}->[0]}[0]{'Date'}[0]){ push @{$folderstructref->{$hashref->{$uid}->{'Message-ID'}->[0]}}, $hashref->{$uid}; push @dup_ids,$uid; } } else{ push @{$folderstructref->{$hashref->{$uid}->{'Message-ID'}->[0]}}, $hashref->{$uid}; } } } } sub print_dups(){ my ($message_id,$dup_group,$i); $dup_group=1; foreach $message_id (keys %$folderstructref){ if (scalar(@{$folderstructref->{$message_id}})>1){ print ("Dup group #$dup_group\n"); for ($i=0;$i{$message_id}});$i++){ print "\t$folderstructref->{$message_id}[$i]{'Date'}[0]\t$folderstructref->{$message_id}[$i]{'Subject'}[0]\n"; } $dup_group++; } } } my $result=getopts('f:u:p:h:d',\%arguments); if ($result==0){ usage(); } if (!$arguments{'u'} || !$arguments{'p'}){ usage(); } my $imapserver=$arguments{'h'}?$arguments{'h'}:$IMAPSERVER; $imap = Mail::IMAPClient->new( Server => $imapserver, User => $arguments{'u'}, Password => $arguments{'p'}, ) or die "Can't connect to $imapserver!\n"; print "Searching for dups in $arguments{'f'}\n"; search_dubs($arguments{'f'}); print_dups(); if ($arguments{'d'}){ delete_dups(); }