This commit is contained in:
Nick Bebout 2011-03-12 02:44:35 +00:00
parent d96755f174
commit 6576e43299
76 changed files with 58645 additions and 2197 deletions

183
imapsync
View file

@ -1,6 +1,7 @@
#!/usr/bin/perl -w
=pod
=head1 NAME
imapsync - IMAP synchronisation, sync, copy or migration
@ -8,7 +9,7 @@ tool. Synchronise mailboxes between two imap servers. Good
at IMAP migration. More than 32 different IMAP server softwares
supported with success.
$Revision: 1.223 $
$Revision: 1.233 $
=head1 INSTALL
@ -16,24 +17,22 @@ $Revision: 1.223 $
imapsync works fine under Windows 2000 (at least) and ActiveState's 5.8 Perl
imapsync is already available directly on the following distributions (at least):
FreeBSD, Debian, Gentoo, NetBSD, Darwin, Mandriva.
imapsync is already available directly on the following distributions:
OpenBSD
FreeBSD, Debian, Ubuntu, Gentoo, NetBSD, Darwin, Mandriva.
Get imapsync at
http://www.linux-france.org/prj/imapsync/dist/
You'll find a compressed tarball called imapsync-x.xx.tgz
where x.xx is the version number. Untar the tarball where
you want :
you want (on Unix):
tar xzvf imapsync-x.xx.tgz
Go into the directory imapsync-x.xx and read the INSTALL
file.
The freshmeat record is http://freshmeat.net/projects/imapsync/
Go into the directory imapsync-x.xx and read the INSTALL file.
The INSTALL file is also at
http://www.linux-france.org/prj/imapsync/INSTALL (for windows users)
The freshmeat record is at http://freshmeat.net/projects/imapsync/
=head1 SYNOPSIS
@ -83,6 +82,7 @@ The option list :
=cut
# comment
=pod
=head1 DESCRIPTION
@ -166,9 +166,10 @@ You may authenticate as one user (typically an admin user),
but be authorized as someone else, which means you don't
need to know every user's personal password. Specify
--authuser1 "adminuser" to enable this on host1. In this
case, --authmech1 PLAIN will be used, but otherwise,
--authmech1 CRAM-MD5 is the default. Same behavior with the
--authuser2 option.
case, --authmech1 PLAIN will be used by default since it
is the only way to go for now. So don't use --authmech1 SOMETHING
with --authuser1 "adminuser", it will not work.
Same behavior with the --authuser2 option.
=head1 EXIT STATUS
@ -236,17 +237,17 @@ In your report, please include:
Failure stories reported with the following 4 imap servers :
- MailEnable 1.54 (Proprietary) http://www.mailenable.com/
- DBMail 2.0.7 (GPL). But DBMail 1.2.1 works.
- DBMail 0.9, 2.0.7 (GPL). But DBMail 1.2.1 works.
Patient and confident testers are welcome.
- dkimap4 2.39
- Imail 7.04 (maybe).
Success stories reported with the following 33 imap servers
Success stories reported with the following 34 imap servers
(softwares names are in alphabetic order) :
- BincImap 1.2.3 (GPL) (http://www.bincimap.org/)
- CommuniGatePro server (Redhat 8.0)
- Courier IMAP 1.5.1, 2.2.0, 2.1.1, 2.2.1 (GPL)
- Courier IMAP 1.5.1, 2.2.0, 2.1.1, 2.2.1, 3.0.8 (GPL)
(http://www.courier-mta.org/)
- Critical Path (7.0.020)
- Cyrus IMAP 1.5, 1.6, 2.1, 2.1.15, 2.1.16, 2.1.18
@ -254,6 +255,7 @@ Success stories reported with the following 33 imap servers
v2.2.3-Invoca-RPM-2.2.3-8,
2.3-alpha (OSI Approved),
v2.2.12-Invoca-RPM-2.2.12-3.RHEL4.1,
2.2.13,
v2.3.1-Invoca-RPM-2.3.1-2.7.fc5,
(http://asg.web.cmu.edu/cyrus/)
- David Tobit V8 (proprietary Message system).
@ -264,6 +266,7 @@ Success stories reported with the following 33 imap servers
1.0.0 [dest] (LGPL) (http://www.dovecot.org/)
- Domino (Notes) 6.5, 5.0.6, 5.0.7, 7.0.2, 6.0.2CF1, 7.0.1 [from]
- Eudora WorldMail v2
- GMX IMAP4 StreamProxy.
- Groupwise IMAP (Novell) 6.x and 7.0. Buggy so see the FAQ.
- iPlanet Messaging server 4.15, 5.1, 5.2
- IMail 7.15 (Ipswitch/Win2003), 8.12
@ -356,24 +359,25 @@ Entries for imapsync:
=head1 SIMILAR SOFTWARES
imap_tools : http://www.athensfbc.com/imap_tools
offlineimap : http://gopher.quux.org:70/devel/offlineimap/
mailsync : http://mailsync.sourceforge.net/
imapxfer : http://www.washington.edu/imap/
part of the imap-utils from UW.
mailutil : replace imapxfer in
part of the imap-utils from UW.
http://www.gsp.com/cgi-bin/man.cgi?topic=mailutil
imaprepl : http://www.bl0rg.net/software/
http://freshmeat.net/projects/imap-repl/
imap_migrate: http://freshmeat.net/projects/imapmigration/
imapcopy : http://home.arcor.de/armin.diehl/imapcopy/imapcopy.html
migrationtool http://sourceforge.net/projects/migrationtool/
pop2imap : http://www.linux-france.org/prj/pop2imap/
imap_tools : http://www.athensfbc.com/imap_tools
offlineimap : http://software.complete.org/offlineimap
mailsync : http://mailsync.sourceforge.net/
imapxfer : http://www.washington.edu/imap/
part of the imap-utils from UW.
mailutil : replace imapxfer in
part of the imap-utils from UW.
http://www.gsp.com/cgi-bin/man.cgi?topic=mailutil
imaprepl : http://www.bl0rg.net/software/
http://freshmeat.net/projects/imap-repl/
imap_migrate : http://freshmeat.net/projects/imapmigration/
imapcopy : http://home.arcor.de/armin.diehl/imapcopy/imapcopy.html
migrationtool : http://sourceforge.net/projects/migrationtool/
imapmigrate : http://sourceforge.net/projects/cyrus-utils/
pop2imap : http://www.linux-france.org/prj/pop2imap/
Feedback (good or bad) will be always welcome.
$Id: imapsync,v 1.223 2007/06/15 04:08:44 gilles Exp gilles $
$Id: imapsync,v 1.233 2007/10/30 03:20:53 gilles Exp gilles $
@ -432,14 +436,14 @@ my(
use vars qw ($opt_G); # missing code for this will be option.
$rcs = ' $Id: imapsync,v 1.223 2007/06/15 04:08:44 gilles Exp gilles $ ';
$rcs = ' $Id: imapsync,v 1.233 2007/10/30 03:20:53 gilles Exp gilles $ ';
$rcs =~ m/,v (\d+\.\d+)/;
$VERSION = ($1) ? $1 : "UNKNOWN";
my $VERSION_IMAPClient = $Mail::IMAPClient::VERSION;
check_lib_version() or
die "Upgrade perl lib Mail::IMAPClient to release 2.2.9 at least\n";
#check_lib_version() or
# die "Upgrade perl lib Mail::IMAPClient to release 2.2.9 at least\n";
$mess_size_total_trans = 0;
@ -469,10 +473,10 @@ $error=0;
my $banner = join("",
'$RCSfile: imapsync,v $ ',
'$Revision: 1.223 $ ',
'$Date: 2007/06/15 04:08:44 $ ',
'$Revision: 1.233 $ ',
'$Date: 2007/10/30 03:20:53 $ ',
"\n",localhost_info(),
"Mail::IMAPClient version used here is ",
" and the module Mail::IMAPClient version used here is ",
$VERSION_IMAPClient,"\n",
"Command line used :\n",
"$0 @ARGV\n",
@ -509,17 +513,20 @@ sub connect_imap {
$imap->Server($host);
$imap->Port($port);
$imap->Debug($debugimap);
$imap->connect()
$imap->connect2()
or die "Can not open imap connection on [$host] : $@\n";
}
sub localhost_info {
my($infos) = join("", "Here is a $OSNAME system",
" ", join(" ", uname()),
")\nwith perl ",
sprintf("%vd", $PERL_VERSION), "\n");
my($infos) = join("",
"Here is a [$OSNAME] system (",
join(" ",
uname(),
),
")\n",
"with perl ",
sprintf("%vd", $PERL_VERSION));
return($infos);
}
@ -550,6 +557,9 @@ if(defined($authmd5) and not($authmd5)) {
$authmech2 ||= $authuser2 ? 'PLAIN' : 'CRAM-MD5';
}
$authmech1 = uc($authmech1);
$authmech2 = uc($authmech2);
$authuser1 ||= $user1;
$authuser2 ||= $user2;
@ -647,7 +657,7 @@ sub login_imap {
if ($ssl) {
$imap->State(Mail::IMAPClient::Connected);
} else {
$imap->connect()
$imap->connect2()
or die "Can not open imap connection on [$host] with user [$user] : $@\n";
}
print "Banner : ", server_banner($imap);
@ -1160,7 +1170,7 @@ FOLDER: foreach my $f_fold (@f_folders) {
$debug and print "internal date from 1: [$d]\n";
require Date::Manip;
Date::Manip->import(qw(ParseDate Date_Cmp UnixDate));
$d = UnixDate(ParseDate($d), "%d %b %Y %H:%M:%S %z");
$d = UnixDate(ParseDate($d), "%d-%b-%Y %H:%M:%S %z");
$d = "\"$d\"";
$debug and print "internal date from 1: [$d] (fixed)\n";
}
@ -1174,17 +1184,22 @@ FOLDER: foreach my $f_fold (@f_folders) {
print "flags from : [$flags_f][$d]\n";
last FOLDER if $to->IsUnconnected();
unless ($dry) {
#unless($new_id = $to->append_string($t_fold,$string, $flags_f, $d)){
unless($new_id = $to->append_file2($t_fold, $message_file, "", $flags_f, $d)){
if ($OSNAME eq "MSWin32") {
$new_id = $to->append_string($t_fold,$string, $flags_f, $d);
}
else {
$new_id = $to->append_file2($t_fold, $message_file, "", $flags_f, $d);
}
unless($new_id){
warn "Couldn't append msg #$f_msg (Subject:[".
$from->subject($f_msg)."]) to folder $t_fold: ",
$to->LastError, "\n";
$error++;
$mess_size_total_error += $f_size;
next MESS;
}else{
# good
# good
# $new_id is an id if the IMAP server has the
# UIDPLUS capability else just a ref
print "Copied msg id [$f_msg] to folder $t_fold msg id [$new_id]\n";
@ -1515,6 +1530,7 @@ sub string_to_file {
sub usage {
my $localhost_info = localhost_info();
print <<EOF;
usage: $0 [options]
@ -1524,7 +1540,8 @@ Several options are mandatory.
--host1 <string> : "from" imap server. Mandatory.
--port1 <int> : port to connect on host1. Default is 143.
--user1 <string> : user to login on host1. Mandatory.
--authuser1 <string> : user to auth with on host1 (admin user).
--authuser1 <string> : user to auth with on host1 (admin user).
Avoid using --authmech1 SOMETHING with --authuser1.
--password1 <string> : password for the user1. Dangerous, use --passfile1
--passfile1 <string> : password file for the user1. Contains the password.
--host2 <string> : "destination" imap server. Mandatory.
@ -1535,7 +1552,7 @@ Several options are mandatory.
--passfile2 <string> : password file for the user2. Contains the password.
--noauthmd5 : don't use MD5 authentification.
--authmech1 <string> : auth mechanism to use with host1:
PLAIN, LOGIN, CRAM-MD5 etc.
PLAIN, LOGIN, CRAM-MD5 etc. Use UPPERCASE.
--authmech2 <string> : auth mechanism to use with host2. See --authmech1
--ssl1 : use an SSL connection on host1.
--ssl2 : use an SSL connection on host2.
@ -1642,7 +1659,7 @@ $0 \\
--host1 imap.truc.org --user1 foo --passfile1 /etc/secret1 \\
--host2 imap.trac.org --user2 bar --passfile2 /etc/secret2
$localhost_info
Mail::IMAPClient version is $Mail::IMAPClient::VERSION
$rcs
imapsync copyleft is the GNU General Public License.
@ -2132,3 +2149,65 @@ sub _cram_md5_2 {
$client->Password());
return MIME::Base64::encode($client->User() . " $hmac", "");
}
sub connect2 {
my $self = shift;
$self->Port(143)
if defined ($IO::Socket::INET::VERSION)
and $IO::Socket::INET::VERSION eq '1.25'
and !$self->Port;
%$self = (%$self, @_);
my $sock = ($self->Ssl ? IO::Socket::SSL->new : IO::Socket::INET->new);
my $dp = ($self->Ssl ? 'imaps(993)' : 'imap(143)');
#print "i01\n";
my $ret = $sock->configure({
PeerAddr => $self->Server ,
PeerPort => $self->Port||$dp ,
Proto => 'tcp' ,
Timeout => $self->Timeout||0 ,
Debug => $self->Debug ,
});
#print "i02\n";
unless ( defined($ret) ) {
$self->LastError( "$@\n");
$@ = "$@";
carp "$@"
unless defined wantarray;
return undef;
}
#print "i03\n";
$self->Socket($sock);
$self->State(Connected);
$sock->autoflush(1) ;
my ($code, $output);
$output = "";
until ( $code ) {
$output = $self->_read_line or return undef;
for my $o (@$output) {
$self->_debug("Connect: Received this from readline: " .
join("/",@$o) . "\n");
$self->_record($self->Count,$o); # $o is a ref
next unless $o->[TYPE] eq "OUTPUT";
($code) = $o->[DATA] =~ /^\*\s+(OK|BAD|NO)/i ;
}
}
if ($code =~ /BYE|NO /) {
$self->State(Unconnected);
return undef ;
}
if ($self->User and $self->Password) {
return $self->login ;
} else {
return $self;
}
}