This commit is contained in:
Nick Bebout 2011-03-12 02:44:50 +00:00
parent f864a2cb10
commit 7299eabfd8
6 changed files with 299 additions and 267 deletions

31
CREDITS
View file

@ -1,5 +1,5 @@
#!/bin/cat #!/bin/cat
# $Id: CREDITS,v 1.127 2009/12/09 00:12:24 gilles Exp gilles $ # $Id: CREDITS,v 1.128 2010/01/16 01:20:06 gilles Exp gilles $
If you want to make a donation to the author, Gilles LAMIRAL: If you want to make a donation to the author, Gilles LAMIRAL:
@ -19,6 +19,26 @@ to remove one.
I thank very much all of these people. I thank very much all of these people.
Robert Bauer
Contributed by giving the book
31.50 "Programming Interactivity: A Designer's Guide to Processing, Arduino, and Openframeworks" by Joshua Noble
R.W. Rodolico
Contributed by giving the book
25.60 "Le Ton Beau De Marot: In Praise Of The Music Of Language" by Clément Marot, Douglas R. Hofstadter
Martin & Simon Clauss
Contributed by giving the book
23.09 "The Best of Instructables Volume I: Do-It-Yourself Projects from the World's Biggest Show & Tell (v. 1)" by MAKE magazine and Instructables.com
Phil Haigh
Contributed by giving the book
29.70 "The Failure of Risk Management: Why It's Broken and How to Fix It" by Douglas W. Hubbard
Frank Justin Woodman
Contributed by giving the book
31.49 "JavaScript: The Definitive Guide" by David Flanagan
Matt Garretson Matt Garretson
Contributed by giving the books Contributed by giving the books
42.66 "Beautiful Testing: Leading Professionals Reveal How They Improve Software (Theory in Practice)" by Adam Goucher 42.66 "Beautiful Testing: Leading Professionals Reveal How They Improve Software (Theory in Practice)" by Adam Goucher
@ -756,7 +776,12 @@ Eric Yung
Total amount of book prices : Total amount of book prices :
c \ c \
31.50+\
25.60+\
23.09+\
29.70+\
31.49+\
\
9.50+\ 9.50+\
\ \
42.66+\ 42.66+\
@ -841,4 +866,4 @@ c \
31.20+\ 31.20+\
40.00 40.00
= =
1985.27 2136.15

View file

@ -1,17 +1,24 @@
RCS file: RCS/imapsync,v RCS file: RCS/imapsync,v
Working file: imapsync Working file: imapsync
head: 1.299 head: 1.300
branch: branch:
locks: strict locks: strict
gilles: 1.299 gilles: 1.300
access list: access list:
symbolic names: symbolic names:
keyword substitution: kv keyword substitution: kv
total revisions: 299; selected revisions: 299 total revisions: 300; selected revisions: 300
description: description:
---------------------------- ----------------------------
revision 1.299 locked by: gilles; revision 1.300 locked by: gilles;
date: 2010/01/16 03:34:37; author: gilles; state: Exp; lines: +250 -250
Changed name of variables. "from" replaced by imap1 "to" by imap2.
f_* replaced by h1_*
t_* replaced by h2_*
Cosmetic but easier to read nd maintain.
----------------------------
revision 1.299
date: 2010/01/15 00:19:32; author: gilles; state: Exp; lines: +10 -10 date: 2010/01/15 00:19:32; author: gilles; state: Exp; lines: +10 -10
imapsync is no longer GPL software. imapsync is no longer GPL software.
imapsync is WTFPL software. The best licence I found. imapsync is WTFPL software. The best licence I found.

8
README
View file

@ -3,7 +3,7 @@ NAME
Synchronise mailboxes between two imap servers. Good at IMAP migration. Synchronise mailboxes between two imap servers. Good at IMAP migration.
More than 32 different IMAP server softwares supported with success. More than 32 different IMAP server softwares supported with success.
$Revision: 1.299 $ $Revision: 1.300 $
INSTALL INSTALL
imapsync works fine under any Unix OS with perl. imapsync works fine under any Unix OS with perl.
@ -301,8 +301,8 @@ IMAP SERVERS
this section report the two lines at the begining of the output if they this section report the two lines at the begining of the output if they
are useful to know the softwares. Example: are useful to know the softwares. Example:
From software:* OK louloutte Cyrus IMAP4 v1.5.19 server ready Host1 software:* OK louloutte Cyrus IMAP4 v1.5.19 server ready
To software:* OK Courier-IMAP ready Host2 software:* OK Courier-IMAP ready
You can use option --justconnect to get those lines. Example: You can use option --justconnect to get those lines. Example:
@ -362,5 +362,5 @@ SIMILAR SOFTWARES
Feedback (good or bad) will always be welcome. Feedback (good or bad) will always be welcome.
$Id: imapsync,v 1.299 2010/01/15 00:19:32 gilles Exp gilles $ $Id: imapsync,v 1.300 2010/01/16 03:34:37 gilles Exp gilles $

12
TODO
View file

@ -1,9 +1,13 @@
#!/bin/cat #!/bin/cat
# $Id: TODO,v 1.69 2010/01/14 23:41:43 gilles Exp gilles $ # $Id: TODO,v 1.70 2010/01/16 03:38:47 gilles Exp gilles $
TODO file for imapsync TODO file for imapsync
---------------------- ----------------------
Post on newsgroup comp.mail.imap when a new release comes.
http://groups.google.fr/group/comp.mail.imap
Post on imapsync mailing-list when a new release comes.
Add option --exclude_messages_with_flag Add option --exclude_messages_with_flag
@ -17,6 +21,7 @@ body. Have to code this.
Add an option to store flags with "FLAGS.SILENT" instead of "+FLAGS.SILENT". Add an option to store flags with "FLAGS.SILENT" instead of "+FLAGS.SILENT".
No, be "FLAGS.SILENT" the default and "+FLAGS.SILENT" an option.
Add TLS support with patches/imapsync-1.217_tls_support.patch Add TLS support with patches/imapsync-1.217_tls_support.patch
@ -29,8 +34,6 @@ Take a look at Mail::IMAPTalk
Simon Bertrang said "way better performance, less problems, easier to use and no Simon Bertrang said "way better performance, less problems, easier to use and no
issues so far". Sounds good! issues so far". Sounds good!
Post on imapsync mailing-list when a new release comes.
Add an option to implement the faq entry about copying a contact folder. Add an option to implement the faq entry about copying a contact folder.
imapsync doesn't report well. It should says "I had imapsync doesn't report well. It should says "I had
@ -118,9 +121,6 @@ Add a method doing the switch automagicaly.
Add --verbose from Kjetil jumbo patch. Add --verbose from Kjetil jumbo patch.
Post on newsgroup comp.mail.imap when a new release comes.
http://groups.google.fr/group/comp.mail.imap
Read the IMAP RFC http://www.faqs.org/rfcs/rfc3501.html Read the IMAP RFC http://www.faqs.org/rfcs/rfc3501.html
Add debian packaging in the Makefile. Add debian packaging in the Makefile.

View file

@ -1 +1 @@
1.299 1.300

498
imapsync
View file

@ -9,7 +9,7 @@ tool. Synchronise mailboxes between two imap servers. Good
at IMAP migration. More than 32 different IMAP server softwares at IMAP migration. More than 32 different IMAP server softwares
supported with success. supported with success.
$Revision: 1.299 $ $Revision: 1.300 $
=head1 INSTALL =head1 INSTALL
@ -336,8 +336,8 @@ future users. To help the author maintaining this section
report the two lines at the begining of the output if they report the two lines at the begining of the output if they
are useful to know the softwares. Example: are useful to know the softwares. Example:
From software:* OK louloutte Cyrus IMAP4 v1.5.19 server ready Host1 software:* OK louloutte Cyrus IMAP4 v1.5.19 server ready
To software:* OK Courier-IMAP ready Host2 software:* OK Courier-IMAP ready
You can use option --justconnect to get those lines. You can use option --justconnect to get those lines.
Example: Example:
@ -418,7 +418,7 @@ Entries for imapsync:
Feedback (good or bad) will always be welcome. Feedback (good or bad) will always be welcome.
$Id: imapsync,v 1.299 2010/01/15 00:19:32 gilles Exp gilles $ $Id: imapsync,v 1.300 2010/01/16 03:34:37 gilles Exp gilles $
=cut =cut
@ -487,7 +487,7 @@ my(
use vars qw ($opt_G); # missing code for this will be option. use vars qw ($opt_G); # missing code for this will be option.
$rcs = '$Id: imapsync,v 1.299 2010/01/15 00:19:32 gilles Exp gilles $ '; $rcs = '$Id: imapsync,v 1.300 2010/01/16 03:34:37 gilles Exp gilles $ ';
$rcs =~ m/,v (\d+\.\d+)/; $rcs =~ m/,v (\d+\.\d+)/;
$VERSION = ($1) ? $1: "UNKNOWN"; $VERSION = ($1) ? $1: "UNKNOWN";
@ -551,8 +551,8 @@ while (@argv_copy) {
my $banner = join("", my $banner = join("",
'$RCSfile: imapsync,v $ ', '$RCSfile: imapsync,v $ ',
'$Revision: 1.299 $ ', '$Revision: 1.300 $ ',
'$Date: 2010/01/15 00:19:32 $ ', '$Date: 2010/01/16 03:34:37 $ ',
"\n",localhost_info(), "\n",localhost_info(),
" and the module Mail::IMAPClient version used here is ", " and the module Mail::IMAPClient version used here is ",
$VERSION_IMAPClient,"\n", $VERSION_IMAPClient,"\n",
@ -643,17 +643,17 @@ sub localhost_info {
} }
if ($justconnect) { if ($justconnect) {
my $from = (); my $imap1 = ();
my $to = (); my $imap2 = ();
$from = connect_imap($host1, $port1, $debugimap, $ssl1); $imap1 = connect_imap($host1, $port1, $debugimap, $ssl1);
print "From software: ", server_banner($from); print "Host1 software: ", server_banner($imap1);
print "From capability: ", join(" ", $from->capability()), "\n"; print "Host1 capability: ", join(" ", $imap1->capability()), "\n";
$to = connect_imap($host2, $port2, $debugimap, $ssl2); $imap2 = connect_imap($host2, $port2, $debugimap, $ssl2);
print "To software: ", server_banner($to); print "Host2 software: ", server_banner($imap2);
print "To capability: ", join(" ", $to->capability()), "\n"; print "Host2 capability: ", join(" ", $imap2->capability()), "\n";
$from->logout(); $imap1->logout();
$to->logout(); $imap2->logout();
exit(0); exit(0);
} }
@ -718,8 +718,8 @@ $fastio2 = (defined($fastio2)) ? $fastio2 : 0;
@useheader = ("ALL") unless (@useheader); @useheader = ("ALL") unless (@useheader);
print "From imap server [$host1] port [$port1] user [$user1]\n"; print "Host1 imap server [$host1] port [$port1] user [$user1]\n";
print "To imap server [$host2] port [$port2] user [$user2]\n"; print "Host2 imap server [$host2] port [$port2] user [$user2]\n";
sub ask_for_password { sub ask_for_password {
@ -746,26 +746,26 @@ $password2 || $passfile2 || do {
$password2 = (defined($passfile2)) ? firstline ($passfile2) : $password2; $password2 = (defined($passfile2)) ? firstline ($passfile2) : $password2;
my $from = (); my $imap1 = ();
my $to = (); my $imap2 = ();
$timestart = time(); $timestart = time();
$timebefore = $timestart; $timebefore = $timestart;
$debugimap and print "From connection\n"; $debugimap and print "Host1 connection\n";
$from = login_imap($host1, $port1, $user1, $password1, $imap1 = login_imap($host1, $port1, $user1, $password1,
$debugimap, $timeout, $fastio1, $ssl1, $debugimap, $timeout, $fastio1, $ssl1,
$authmech1, $authuser1, $reconnectretry1); $authmech1, $authuser1, $reconnectretry1);
$debugimap and print "To connection\n"; $debugimap and print "Host2 connection\n";
$to = login_imap($host2, $port2, $user2, $password2, $imap2 = login_imap($host2, $port2, $user2, $password2,
$debugimap, $timeout, $fastio2, $ssl2, $debugimap, $timeout, $fastio2, $ssl2,
$authmech2, $authuser2, $reconnectretry2); $authmech2, $authuser2, $reconnectretry2);
# history # history
$debug and print "From Buffer I/O: ", $from->Buffer(), "\n"; $debug and print "Host1 Buffer I/O: ", $imap1->Buffer(), "\n";
$debug and print "To Buffer I/O: ", $to->Buffer(), "\n"; $debug and print "Host2 Buffer I/O: ", $imap2->Buffer(), "\n";
sub login_imap { sub login_imap {
@ -856,24 +856,24 @@ sub server_banner {
$debug and print "From capability: ", join(" ", $from->capability()), "\n"; $debug and print "Host1 capability: ", join(" ", $imap1->capability()), "\n";
$debug and print "To capability: ", join(" ", $to->capability()), "\n"; $debug and print "Host2 capability: ", join(" ", $imap2->capability()), "\n";
die unless $from->IsAuthenticated(); die unless $imap1->IsAuthenticated();
print "host1: state Authenticated\n"; print "host1: state Authenticated\n";
die unless $to->IsAuthenticated(); die unless $imap2->IsAuthenticated();
print "host2: state Authenticated\n"; print "host2: state Authenticated\n";
exit(0) if ($justlogin); exit(0) if ($justlogin);
$split1 and $from->Split($split1); $split1 and $imap1->Split($split1);
$split2 and $to->Split($split2); $split2 and $imap2->Split($split2);
# #
# Folder stuff # Folder stuff
# #
my (@f_folders, %requested_folder, @t_folders, @t_folders_list, %t_folders_list, %subscribed_folder, %t_folders); my (@h1_folders, %requested_folder, @h2_folders, @h2_folders_list, %h2_folders_list, %subscribed_folder, %h2_folders);
sub tests_folder_routines { sub tests_folder_routines {
ok( !give_requested_folders() ,"no requested folders" ); ok( !give_requested_folders() ,"no requested folders" );
@ -931,7 +931,7 @@ sub remove_from_requested_folders {
# Make a hash of subscribed folders in source server. # Make a hash of subscribed folders in source server.
map { $subscribed_folder{$_} = 1 } $from->subscribed(); map { $subscribed_folder{$_} = 1 } $imap1->subscribed();
@ -950,7 +950,7 @@ if (scalar(@folder) or $subscribed or scalar(@folderrec)) {
# option --folderrec # option --folderrec
if (scalar(@folderrec)) { if (scalar(@folderrec)) {
foreach my $folderrec (@folderrec) { foreach my $folderrec (@folderrec) {
add_to_requested_folders($from->folders($folderrec)); add_to_requested_folders($imap1->folders($folderrec));
} }
} }
} }
@ -958,7 +958,7 @@ else {
# no include, no folder/subscribed/folderrec options => all folders # no include, no folder/subscribed/folderrec options => all folders
if (not scalar(@include)) { if (not scalar(@include)) {
my @all_source_folders = sort $from->folders(); my @all_source_folders = sort $imap1->folders();
add_to_requested_folders(@all_source_folders); add_to_requested_folders(@all_source_folders);
} }
} }
@ -966,7 +966,7 @@ else {
# consider (optional) includes and excludes # consider (optional) includes and excludes
if (scalar(@include)) { if (scalar(@include)) {
my @all_source_folders = sort $from->folders(); my @all_source_folders = sort $imap1->folders();
foreach my $include (@include) { foreach my $include (@include) {
my @included_folders = grep /$include/, @all_source_folders; my @included_folders = grep /$include/, @all_source_folders;
add_to_requested_folders(@included_folders); add_to_requested_folders(@included_folders);
@ -986,7 +986,7 @@ if (scalar(@exclude)) {
# Remove no selectable folders # Remove no selectable folders
foreach my $folder (keys(%requested_folder)) { foreach my $folder (keys(%requested_folder)) {
if ( not $from->selectable($folder)) { if ( not $imap1->selectable($folder)) {
print "Warning: ignoring folder $folder because it is not selectable\n"; print "Warning: ignoring folder $folder because it is not selectable\n";
remove_from_requested_folders($folder); remove_from_requested_folders($folder);
} }
@ -995,7 +995,7 @@ foreach my $folder (keys(%requested_folder)) {
my @requested_folder = sort(keys(%requested_folder)); my @requested_folder = sort(keys(%requested_folder));
@f_folders = @requested_folder; @h1_folders = @requested_folder;
sub compare_lists { sub compare_lists {
my ($list_1_ref, $list_2_ref) = @_; my ($list_1_ref, $list_2_ref) = @_;
@ -1071,22 +1071,22 @@ sub tests_compare_lists {
my($f_sep,$t_sep); my($h1_sep,$h2_sep);
# what are the private folders separators for each server ? # what are the private folders separators for each server ?
$debug and print "Getting separators\n"; $debug and print "Getting separators\n";
$f_sep = get_separator($from, $sep1, "--sep1"); $h1_sep = get_separator($imap1, $sep1, "--sep1");
$t_sep = get_separator($to, $sep2, "--sep2"); $h2_sep = get_separator($imap2, $sep2, "--sep2");
#my $f_namespace = $from->namespace(); #my $h1_namespace = $imap1->namespace();
#my $t_namespace = $to->namespace(); #my $h2_namespace = $imap2->namespace();
#$debug and print "From namespace:\n", Data::Dumper->Dump([$f_namespace]); #$debug and print "Host1 namespace:\n", Data::Dumper->Dump([$h1_namespace]);
#$debug and print "To namespace:\n", Data::Dumper->Dump([$t_namespace]); #$debug and print "Host2 namespace:\n", Data::Dumper->Dump([$h2_namespace]);
my($f_prefix,$t_prefix); my($h1_prefix,$h2_prefix);
$f_prefix = get_prefix($from, $prefix1, "--prefix1"); $h1_prefix = get_prefix($imap1, $prefix1, "--prefix1");
$t_prefix = get_prefix($to, $prefix2, "--prefix2"); $h2_prefix = get_prefix($imap2, $prefix2, "--prefix2");
sub get_prefix { sub get_prefix {
my($imap, $prefix_in, $prefix_opt) = @_; my($imap, $prefix_in, $prefix_opt) = @_;
@ -1143,8 +1143,8 @@ sub get_separator {
} }
print "From separator and prefix: [$f_sep][$f_prefix]\n"; print "Host1 separator and prefix: [$h1_sep][$h1_prefix]\n";
print "To separator and prefix: [$t_sep][$t_prefix]\n"; print "Host2 separator and prefix: [$h2_sep][$h2_prefix]\n";
sub foldersizes { sub foldersizes {
@ -1201,17 +1201,17 @@ sub foldersizes {
} }
foreach my $f_fold (@f_folders) { foreach my $h1_fold (@h1_folders) {
my $t_fold; my $h2_fold;
$t_fold = to_folder_name($f_fold); $h2_fold = to_folder_name($h1_fold);
$t_folders{$t_fold}++; $h2_folders{$h2_fold}++;
} }
@t_folders = sort keys(%t_folders); @h2_folders = sort keys(%h2_folders);
if ($foldersizes) { if ($foldersizes) {
foldersizes("From", $from, \@f_folders); foldersizes("Host1", $imap1, \@h1_folders);
foldersizes("To ", $to, \@t_folders); foldersizes("Host2", $imap2, \@h2_folders);
} }
@ -1229,21 +1229,21 @@ sub timenext {
exit if ($justfoldersizes); exit if ($justfoldersizes);
# needed for setting flags # needed for setting flags
my $tohasuidplus = $to->has_capability("UIDPLUS"); my $imap2hasuidplus = $imap2->has_capability("UIDPLUS");
@t_folders_list = sort @{$to->folders()}; @h2_folders_list = sort @{$imap2->folders()};
foreach my $folder (@t_folders_list) { foreach my $folder (@h2_folders_list) {
$t_folders_list{$folder}++; $h2_folders_list{$folder}++;
} }
print print
"++++ Listing folders ++++\n", "++++ Listing folders ++++\n",
"From folders list:\n", map("[$_]\n",@f_folders),"\n", "Host1 folders list:\n", map("[$_]\n",@h1_folders),"\n",
"To folders list:\n", map("[$_]\n",@t_folders_list),"\n"; "Host2 folders list:\n", map("[$_]\n",@h2_folders_list),"\n";
print print
"From subscribed folders list: ", "Host1 subscribed folders list: ",
map("[$_] ", sort keys(%subscribed_folder)), "\n" map("[$_] ", sort keys(%subscribed_folder)), "\n"
if ($subscribed); if ($subscribed);
@ -1251,35 +1251,35 @@ sub separator_invert {
# The separator we hope we'll never encounter: 00000000 # The separator we hope we'll never encounter: 00000000
my $o_sep="\000"; my $o_sep="\000";
my($f_fold, $f_sep, $t_sep) = @_; my($h1_fold, $h1_sep, $h2_sep) = @_;
my $t_fold = $f_fold; my $h2_fold = $h1_fold;
$t_fold =~ s@\Q$t_sep@$o_sep@g; $h2_fold =~ s@\Q$h2_sep@$o_sep@g;
$t_fold =~ s@\Q$f_sep@$t_sep@g; $h2_fold =~ s@\Q$h1_sep@$h2_sep@g;
$t_fold =~ s@\Q$o_sep@$f_sep@g; $h2_fold =~ s@\Q$o_sep@$h1_sep@g;
return($t_fold); return($h2_fold);
} }
sub to_folder_name { sub to_folder_name {
my ($t_fold); my ($h2_fold);
my ($x_fold) = @_; my ($x_fold) = @_;
# first we remove the prefix # first we remove the prefix
$x_fold =~ s/^\Q$f_prefix\E//; $x_fold =~ s/^\Q$h1_prefix\E//;
$debug and print "removed source prefix: [$x_fold]\n"; $debug and print "removed source prefix: [$x_fold]\n";
$t_fold = separator_invert($x_fold,$f_sep, $t_sep); $h2_fold = separator_invert($x_fold,$h1_sep, $h2_sep);
$debug and print "inverted separators: [$t_fold]\n"; $debug and print "inverted separators: [$h2_fold]\n";
# Adding the prefix supplied by namespace or the --prefix2 option # Adding the prefix supplied by namespace or the --prefix2 option
$t_fold = $t_prefix . $t_fold $h2_fold = $h2_prefix . $h2_fold
unless(($t_prefix eq "INBOX" . $t_sep) and ($t_fold =~ m/^INBOX$/i)); unless(($h2_prefix eq "INBOX" . $h2_sep) and ($h2_fold =~ m/^INBOX$/i));
$debug and print "added target prefix: [$t_fold]\n"; $debug and print "added target prefix: [$h2_fold]\n";
# Transforming the folder name by the --regextrans2 option(s) # Transforming the folder name by the --regextrans2 option(s)
foreach my $regextrans2 (@regextrans2) { foreach my $regextrans2 (@regextrans2) {
$debug and print "eval \$t_fold =~ $regextrans2\n"; $debug and print "eval \$h2_fold =~ $regextrans2\n";
eval("\$t_fold =~ $regextrans2"); eval("\$h2_fold =~ $regextrans2");
die("error: eval regextrans2 '$regextrans2': $@\n") if $@; die("error: eval regextrans2 '$regextrans2': $@\n") if $@;
} }
return($t_fold); return($h2_fold);
} }
sub tests_flags_regex { sub tests_flags_regex {
@ -1313,21 +1313,21 @@ sub flags_regex {
} }
sub acls_sync { sub acls_sync {
my($f_fold, $t_fold) = @_; my($h1_fold, $h2_fold) = @_;
if ($syncacls) { if ($syncacls) {
my $f_hash = $from->getacl($f_fold) my $h1_hash = $imap1->getacl($h1_fold)
or warn "Could not getacl for $f_fold: $@\n"; or warn "Could not getacl for $h1_fold: $@\n";
my $t_hash = $to->getacl($t_fold) my $h2_hash = $imap2->getacl($h2_fold)
or warn "Could not getacl for $t_fold: $@\n"; or warn "Could not getacl for $h2_fold: $@\n";
my %users = map({ ($_, 1) } (keys(%$f_hash), keys(%$t_hash))); my %users = map({ ($_, 1) } (keys(%$h1_hash), keys(%$h2_hash)));
foreach my $user (sort(keys(%users))) { foreach my $user (sort(keys(%users))) {
my $acl = $f_hash->{$user} || "none"; my $acl = $h1_hash->{$user} || "none";
print "acl $user: [$acl]\n"; print "acl $user: [$acl]\n";
next if ($f_hash->{$user} && $t_hash->{$user} && next if ($h1_hash->{$user} && $h2_hash->{$user} &&
$f_hash->{$user} eq $t_hash->{$user}); $h1_hash->{$user} eq $h2_hash->{$user});
unless ($dry) { unless ($dry) {
print "setting acl $t_fold $user $acl\n"; print "setting acl $h2_fold $user $acl\n";
$to->setacl($t_fold, $user, $acl) $imap2->setacl($h2_fold, $user, $acl)
or warn "Could not set acl: $@\n"; or warn "Could not set acl: $@\n";
} }
} }
@ -1393,30 +1393,30 @@ sub flags_filter {
print "++++ Looping on each folder ++++\n"; print "++++ Looping on each folder ++++\n";
FOLDER: foreach my $f_fold (@f_folders) { FOLDER: foreach my $h1_fold (@h1_folders) {
my $t_fold; my $h2_fold;
print "From Folder [$f_fold]\n"; print "Host1 Folder [$h1_fold]\n";
$t_fold = to_folder_name($f_fold); $h2_fold = to_folder_name($h1_fold);
print "To Folder [$t_fold]\n"; print "Host2 Folder [$h2_fold]\n";
last FOLDER if $from->IsUnconnected(); last FOLDER if $imap1->IsUnconnected();
last FOLDER if $to->IsUnconnected(); last FOLDER if $imap2->IsUnconnected();
unless ($from->select($f_fold)) { unless ($imap1->select($h1_fold)) {
warn warn
"From Folder $f_fold: Could not select: ", "Host1 Folder $h1_fold: Could not select: ",
$from->LastError, "\n"; $imap1->LastError, "\n";
$error++; $error++;
next FOLDER; next FOLDER;
} }
if ( ! exists($t_folders_list{$t_fold})) { if ( ! exists($h2_folders_list{$h2_fold})) {
print "To Folder $t_fold does not exist\n"; print "Host2 folder $h2_fold does not exist\n";
print "Creating folder [$t_fold]\n"; print "Creating folder [$h2_fold]\n";
unless ($dry){ unless ($dry){
unless ($to->create($t_fold)){ unless ($imap2->create($h2_fold)){
warn "Couldn't create [$t_fold]: ", warn "Couldn't create [$h2_fold]: ",
$to->LastError,"\n"; $imap2->LastError,"\n";
$error++; $error++;
next FOLDER; next FOLDER;
} }
@ -1426,186 +1426,186 @@ FOLDER: foreach my $f_fold (@f_folders) {
} }
} }
acls_sync($f_fold, $t_fold); acls_sync($h1_fold, $h2_fold);
unless ($to->select($t_fold)) { unless ($imap2->select($h2_fold)) {
warn warn
"To Folder $t_fold: Could not select: ", "Host2 folder $h2_fold: Could not select: ",
$to->LastError, "\n"; $imap2->LastError, "\n";
$error++; $error++;
next FOLDER; next FOLDER;
} }
my @select_results = $to->Results(); my @select_results = $imap2->Results();
#print "%%% @select_results\n"; #print "%%% @select_results\n";
my $permanentflags2 = permanentflags(@select_results); my $permanentflags2 = permanentflags(@select_results);
if ($expunge){ if ($expunge){
print "Expunging host1 $f_fold\n"; print "Expunging host1 $h1_fold\n";
unless($dry) { $from->expunge() }; unless($dry) { $imap1->expunge() };
#print "Expunging host2 $t_fold\n"; #print "Expunging host2 $h2_fold\n";
#unless($dry) { $to->expunge() }; #unless($dry) { $imap2->expunge() };
} }
if ($subscribe and exists $subscribed_folder{$f_fold}) { if ($subscribe and exists $subscribed_folder{$h1_fold}) {
print "Subscribing to folder $t_fold on destination server\n"; print "Subscribing to folder $h2_fold on destination server\n";
unless($dry) { $to->subscribe($t_fold) }; unless($dry) { $imap2->subscribe($h2_fold) };
} }
next FOLDER if ($justfolders); next FOLDER if ($justfolders);
last FOLDER if $from->IsUnconnected(); last FOLDER if $imap1->IsUnconnected();
last FOLDER if $to->IsUnconnected(); last FOLDER if $imap2->IsUnconnected();
my @f_msgs = select_msgs($from); my @h1_msgs = select_msgs($imap1);
$debug and print "LIST FROM: ", scalar(@f_msgs), " messages [@f_msgs]\n"; $debug and print "LIST FROM: ", scalar(@h1_msgs), " messages [@h1_msgs]\n";
# internal dates on "TO" are after the ones on "FROM" # internal dates on "TO" are after the ones on "FROM"
# normally... # normally...
my @t_msgs = select_msgs($to); my @h2_msgs = select_msgs($imap2);
$debug and print "LIST TO : ", scalar(@t_msgs), " messages [@t_msgs]\n"; $debug and print "LIST TO : ", scalar(@h2_msgs), " messages [@h2_msgs]\n";
my %f_hash = (); my %h1_hash = ();
my %t_hash = (); my %h2_hash = ();
#print "++++ Using cache ++++\n"; #print "++++ Using cache ++++\n";
print "++++ From [$f_fold] Parse 1 ++++\n"; print "++++ Host1 [$h1_fold] Parse 1 ++++\n";
last FOLDER if $from->IsUnconnected(); last FOLDER if $imap1->IsUnconnected();
last FOLDER if $to->IsUnconnected(); last FOLDER if $imap2->IsUnconnected();
my ($f_heads, $f_fir) = ({}, {}); my ($h1_heads, $h1_fir) = ({}, {});
$f_heads = $from->parse_headers([@f_msgs], @useheader) if (@f_msgs); $h1_heads = $imap1->parse_headers([@h1_msgs], @useheader) if (@h1_msgs);
$debug and print "Time headers: ", timenext(), " s\n"; $debug and print "Time headers: ", timenext(), " s\n";
last FOLDER if $from->IsUnconnected(); last FOLDER if $imap1->IsUnconnected();
$f_fir = $from->fetch_hash("FLAGS", "INTERNALDATE", "RFC822.SIZE") $h1_fir = $imap1->fetch_hash("FLAGS", "INTERNALDATE", "RFC822.SIZE")
if (@f_msgs); if (@h1_msgs);
$debug and print "Time fir: ", timenext(), " s\n"; $debug and print "Time fir: ", timenext(), " s\n";
unless ($f_fir) { unless ($h1_fir) {
warn warn
"From Folder $f_fold: Could not fetch_hash ", "Host1 Folder $h1_fold: Could not fetch_hash ",
scalar(@f_msgs), " msgs: ", $from->LastError, "\n"; scalar(@h1_msgs), " msgs: ", $imap1->LastError, "\n";
$error++; $error++;
next FOLDER; next FOLDER;
} }
last FOLDER if $from->IsUnconnected(); last FOLDER if $imap1->IsUnconnected();
foreach my $m (@f_msgs) { foreach my $m (@h1_msgs) {
my $rc = parse_header_msg1($from, $m, $f_heads, $f_fir, "F", \%f_hash); my $rc = parse_header_msg1($imap1, $m, $h1_heads, $h1_fir, "F", \%h1_hash);
if (!$rc) { if (!$rc) {
my $reason = !defined($rc) ? "no header" : "duplicate"; my $reason = !defined($rc) ? "no header" : "duplicate";
my $f_size = $f_fir->{$m}->{"RFC822.SIZE"} || 0; my $h1_size = $h1_fir->{$m}->{"RFC822.SIZE"} || 0;
print "+ Skipping msg #$m:$f_size in folder $f_fold ($reason so we ignore this message)\n"; print "+ Skipping msg #$m:$h1_size in folder $h1_fold ($reason so we ignore this message)\n";
$mess_size_total_skipped += $f_size; $mess_size_total_skipped += $h1_size;
$mess_skipped += 1; $mess_skipped += 1;
} }
} }
$debug and print "Time headers: ", timenext(), " s\n"; $debug and print "Time headers: ", timenext(), " s\n";
print "++++ To [$t_fold] Parse 1 ++++\n"; print "++++ Host2 [$h2_fold] Parse 1 ++++\n";
my ($t_heads, $t_fir) = ({}, {}); my ($h2_heads, $h2_fir) = ({}, {});
$t_heads = $to->parse_headers([@t_msgs], @useheader) if (@t_msgs); $h2_heads = $imap2->parse_headers([@h2_msgs], @useheader) if (@h2_msgs);
$debug and print "Time headers: ", timenext(), " s\n"; $debug and print "Time headers: ", timenext(), " s\n";
last FOLDER if $to->IsUnconnected(); last FOLDER if $imap2->IsUnconnected();
$t_fir = $to->fetch_hash("FLAGS", "INTERNALDATE", "RFC822.SIZE") $h2_fir = $imap2->fetch_hash("FLAGS", "INTERNALDATE", "RFC822.SIZE")
if (@t_msgs); if (@h2_msgs);
$debug and print "Time fir: ", timenext(), " s\n"; $debug and print "Time fir: ", timenext(), " s\n";
last FOLDER if $to->IsUnconnected(); last FOLDER if $imap2->IsUnconnected();
foreach my $m (@t_msgs) { foreach my $m (@h2_msgs) {
my $rc = parse_header_msg1($to, $m, $t_heads, $t_fir, "T", \%t_hash); my $rc = parse_header_msg1($imap2, $m, $h2_heads, $h2_fir, "T", \%h2_hash);
if (!$rc) { if (!$rc) {
my $reason = !defined($rc) ? "no header" : "duplicate"; my $reason = !defined($rc) ? "no header" : "duplicate";
my $t_size = $t_fir->{$m}->{"RFC822.SIZE"} || 0; my $h2_size = $h2_fir->{$m}->{"RFC822.SIZE"} || 0;
print "+ Skipping msg #$m:$t_size in 'to' folder $t_fold ($reason so we ignore this message)\n"; print "+ Skipping msg #$m:$h2_size in 'to' folder $h2_fold ($reason so we ignore this message)\n";
#$mess_size_total_skipped += $msize; #$mess_size_total_skipped += $msize;
#$mess_skipped += 1; #$mess_skipped += 1;
} }
} }
$debug and print "Time headers: ", timenext(), " s\n"; $debug and print "Time headers: ", timenext(), " s\n";
print "++++ Verifying [$f_fold] -> [$t_fold] ++++\n"; print "++++ Verifying [$h1_fold] -> [$h2_fold] ++++\n";
# messages in "from" that are not good in "to" # messages in "from" that are not good in "to"
my @f_hash_keys_sorted_by_uid my @h1_hash_keys_sorted_by_uid
= sort {$f_hash{$a}{'m'} <=> $f_hash{$b}{'m'}} keys(%f_hash); = sort {$h1_hash{$a}{'m'} <=> $h1_hash{$b}{'m'}} keys(%h1_hash);
#print map { $f_hash{$_}{'m'} . " "} @f_hash_keys_sorted_by_uid; #print map { $h1_hash{$_}{'m'} . " "} @h1_hash_keys_sorted_by_uid;
my @t_hash_keys_sorted_by_uid my @h2_hash_keys_sorted_by_uid
= sort {$t_hash{$a}{'m'} <=> $t_hash{$b}{'m'}} keys(%t_hash); = sort {$h2_hash{$a}{'m'} <=> $h2_hash{$b}{'m'}} keys(%h2_hash);
if($delete2) { if($delete2) {
my @expunge; my @expunge;
foreach my $m_id (@t_hash_keys_sorted_by_uid) { foreach my $m_id (@h2_hash_keys_sorted_by_uid) {
#print "$m_id "; #print "$m_id ";
unless (exists($f_hash{$m_id})) { unless (exists($h1_hash{$m_id})) {
my $t_msg = $t_hash{$m_id}{'m'}; my $h2_msg = $h2_hash{$m_id}{'m'};
my $flags = $t_hash{$m_id}{'F'} || ""; my $flags = $h2_hash{$m_id}{'F'} || "";
my $isdel = $flags =~ /\B\\Deleted\b/ ? 1 : 0; my $isdel = $flags =~ /\B\\Deleted\b/ ? 1 : 0;
print "deleting message $m_id $t_msg\n" print "deleting message $m_id $h2_msg\n"
if ! $isdel; if ! $isdel;
push(@expunge,$t_msg) if $uidexpunge2; push(@expunge,$h2_msg) if $uidexpunge2;
unless ($dry or $isdel) { unless ($dry or $isdel) {
$to->delete_message($t_msg); $imap2->delete_message($h2_msg);
last FOLDER if $to->IsUnconnected(); last FOLDER if $imap2->IsUnconnected();
} }
} }
} }
my $cnt = scalar @expunge; my $cnt = scalar @expunge;
if(@expunge and !$to->can("uidexpunge")) { if(@expunge and !$imap2->can("uidexpunge")) {
warn "uidexpunge not supported (< IMAPClient 3.17)\n"; warn "uidexpunge not supported (< IMAPClient 3.17)\n";
} }
elsif(@expunge) { elsif(@expunge) {
print "uidexpunge $cnt message(s)\n"; print "uidexpunge $cnt message(s)\n";
$to->uidexpunge(\@expunge) if !$dry; $imap2->uidexpunge(\@expunge) if !$dry;
} }
} }
MESS: foreach my $m_id (@f_hash_keys_sorted_by_uid) { MESS: foreach my $m_id (@h1_hash_keys_sorted_by_uid) {
my $f_size = $f_hash{$m_id}{'s'}; my $h1_size = $h1_hash{$m_id}{'s'};
my $f_msg = $f_hash{$m_id}{'m'}; my $h1_msg = $h1_hash{$m_id}{'m'};
my $f_idate = $f_hash{$m_id}{'D'}; my $h1_idate = $h1_hash{$m_id}{'D'};
if (defined $maxsize and $f_size > $maxsize) { if (defined $maxsize and $h1_size > $maxsize) {
print "+ Skipping msg #$f_msg:$f_size in folder $f_fold (exceeds maxsize limit $maxsize bytes)\n"; print "+ Skipping msg #$h1_msg:$h1_size in folder $h1_fold (exceeds maxsize limit $maxsize bytes)\n";
$mess_size_total_skipped += $f_size; $mess_size_total_skipped += $h1_size;
$mess_skipped += 1; $mess_skipped += 1;
next MESS; next MESS;
} }
$debug and print "+ key $m_id #$f_msg\n"; $debug and print "+ key $m_id #$h1_msg\n";
unless (exists($t_hash{$m_id})) { unless (exists($h2_hash{$m_id})) {
print "+ NO msg #$f_msg [$m_id] in $t_fold\n"; print "+ NO msg #$h1_msg [$m_id] in $h2_fold\n";
# copy # copy
print "+ Copying msg #$f_msg:$f_size to folder $t_fold\n"; print "+ Copying msg #$h1_msg:$h1_size to folder $h2_fold\n";
last FOLDER if $from->IsUnconnected(); last FOLDER if $imap1->IsUnconnected();
last FOLDER if $to->IsUnconnected(); last FOLDER if $imap2->IsUnconnected();
my $string; my $string;
$string = $from->message_string($f_msg); $string = $imap1->message_string($h1_msg);
unless (defined($string)) { unless (defined($string)) {
warn warn
"Could not fetch message #$f_msg from $f_fold: ", "Could not fetch message #$h1_msg from $h1_fold: ",
$from->LastError, "\n"; $imap1->LastError, "\n";
$error++; $error++;
$mess_size_total_error += $f_size; $mess_size_total_error += $h1_size;
next MESS; next MESS;
} }
#print "AAAmessage_string[$string]ZZZ\n"; #print "AAAmessage_string[$string]ZZZ\n";
#my $message_file = "tmp_imapsync_$$"; #my $message_file = "tmp_imapsync_$$";
#$from->select($f_fold); #$imap1->select($h1_fold);
#unlink($message_file); #unlink($message_file);
#$from->message_to_file($message_file, $f_msg) or do { #$imap1->message_to_file($message_file, $h1_msg) or do {
# warn "Could not put message #$f_msg to file $message_file", # warn "Could not put message #$h1_msg to file $message_file",
# $from->LastError; # $imap1->LastError;
# $error++; # $error++;
# $mess_size_total_error += $f_size; # $mess_size_total_error += $h1_size;
# next MESS; # next MESS;
#}; #};
#$string = file_to_string($message_file); #$string = file_to_string($message_file);
@ -1649,7 +1649,7 @@ FOLDER: foreach my $f_fold (@f_folders) {
"F message content ended on previous line\n", "=" x 80, "\n"; "F message content ended on previous line\n", "=" x 80, "\n";
my $d = ""; my $d = "";
if ($syncinternaldates) { if ($syncinternaldates) {
$d = $f_idate; $d = $h1_idate;
$debug and print "internal date from 1: [$d]\n"; $debug and print "internal date from 1: [$d]\n";
$d = good_date($d); $d = good_date($d);
$debug and print "internal date from 1: [$d] (fixed)\n"; $debug and print "internal date from 1: [$d] (fixed)\n";
@ -1657,7 +1657,7 @@ FOLDER: foreach my $f_fold (@f_folders) {
if ($idatefromheader) { if ($idatefromheader) {
$d = $from->get_header($f_msg,"Date"); $d = $imap1->get_header($h1_msg,"Date");
$debug and print "header date from 1: [$d]\n"; $debug and print "header date from 1: [$d]\n";
$d = good_date($d); $d = good_date($d);
$debug and print "header date from 1: [$d] (fixed)\n"; $debug and print "header date from 1: [$d] (fixed)\n";
@ -1670,7 +1670,7 @@ FOLDER: foreach my $f_fold (@f_folders) {
return($d); return($d);
} }
my $flags_f = $f_hash{$m_id}{'F'} || ""; my $flags_f = $h1_hash{$m_id}{'F'} || "";
# RFC 2060: This flag can not be altered by any client # RFC 2060: This flag can not be altered by any client
$flags_f =~ s@\\Recent\s?@@gi; $flags_f =~ s@\\Recent\s?@@gi;
$flags_f = flags_regex($flags_f) if @regexflag; $flags_f = flags_regex($flags_f) if @regexflag;
@ -1679,42 +1679,42 @@ FOLDER: foreach my $f_fold (@f_folders) {
my $new_id; my $new_id;
print "flags from: [$flags_f][$d]\n"; print "flags from: [$flags_f][$d]\n";
last FOLDER if $from->IsUnconnected(); last FOLDER if $imap1->IsUnconnected();
last FOLDER if $to->IsUnconnected(); last FOLDER if $imap2->IsUnconnected();
unless ($dry) { unless ($dry) {
if ($OSNAME eq "MSWin32") { if ($OSNAME eq "MSWin32") {
$new_id = $to->append_string($t_fold,$string, $flags_f, $d); $new_id = $imap2->append_string($h2_fold,$string, $flags_f, $d);
} }
else { else {
# just back to append_string since append_file 3.05 does not work. # just back to append_string since append_file 3.05 does not work.
#$new_id = $to->append_file($t_fold, $message_file, "", $flags_f, $d); #$new_id = $imap2->append_file($h2_fold, $message_file, "", $flags_f, $d);
# append_string 3.05 does not work too some times with $d unset. # append_string 3.05 does not work too some times with $d unset.
$new_id = $to->append_string($t_fold,$string, $flags_f, $d); $new_id = $imap2->append_string($h2_fold,$string, $flags_f, $d);
} }
unless($new_id){ unless($new_id){
no warnings 'uninitialized'; no warnings 'uninitialized';
warn "Couldn't append msg #$f_msg (Subject:[". warn "Couldn't append msg #$h1_msg (Subject:[".
$from->subject($f_msg)."]) to folder $t_fold: ", $imap1->subject($h1_msg)."]) to folder $h2_fold: ",
$to->LastError, "\n"; $imap2->LastError, "\n";
$error++; $error++;
$mess_size_total_error += $f_size; $mess_size_total_error += $h1_size;
next MESS; next MESS;
} }
else{ else{
# good # good
# $new_id is an id if the IMAP server has the # $new_id is an id if the IMAP server has the
# UIDPLUS capability else just a ref # UIDPLUS capability else just a ref
print "Copied msg id [$f_msg] to folder $t_fold msg id [$new_id]\n"; print "Copied msg id [$h1_msg] to folder $h2_fold msg id [$new_id]\n";
$mess_size_total_trans += $f_size; $mess_size_total_trans += $h1_size;
$mess_trans += 1; $mess_trans += 1;
if($delete) { if($delete) {
print "Deleting msg #$f_msg in folder $f_fold\n"; print "Deleting msg #$h1_msg in folder $h1_fold\n";
unless($dry) { unless($dry) {
$from->delete_message($f_msg); $imap1->delete_message($h1_msg);
last FOLDER if $from->IsUnconnected(); last FOLDER if $imap1->IsUnconnected();
$from->expunge() if ($expunge); $imap1->expunge() if ($expunge);
last FOLDER if $from->IsUnconnected(); last FOLDER if $imap1->IsUnconnected();
} }
} }
} }
@ -1726,19 +1726,19 @@ FOLDER: foreach my $f_fold (@f_folders) {
next MESS; next MESS;
} }
else{ else{
$debug and print "Message id [$m_id] found in t:$t_fold\n"; $debug and print "Message id [$m_id] found in t:$h2_fold\n";
$mess_size_total_skipped += $f_size; $mess_size_total_skipped += $h1_size;
$mess_skipped += 1; $mess_skipped += 1;
} }
$fast and next MESS; $fast and next MESS;
#$debug and print "MESSAGE $m_id\n"; #$debug and print "MESSAGE $m_id\n";
my $t_size = $t_hash{$m_id}{'s'}; my $h2_size = $h2_hash{$m_id}{'s'};
my $t_msg = $t_hash{$m_id}{'m'}; my $h2_msg = $h2_hash{$m_id}{'m'};
# used cached flag values for efficiency # used cached flag values for efficiency
my $flags_f = $f_hash{$m_id}{'F'} || ""; my $flags_f = $h1_hash{$m_id}{'F'} || "";
my $flags_t = $t_hash{$m_id}{'F'} || ""; my $flags_t = $h2_hash{$m_id}{'F'} || "";
# RFC 2060: This flag can not be altered by any client # RFC 2060: This flag can not be altered by any client
$flags_f =~ s@\\Recent\s?@@gi; $flags_f =~ s@\\Recent\s?@@gi;
@ -1749,29 +1749,29 @@ FOLDER: foreach my $f_fold (@f_folders) {
my %ft = map { $_ => 1 } split(' ', $flags_t ); my %ft = map { $_ => 1 } split(' ', $flags_t );
my @flags_a = map { exists $ft{$_} ? () : $_ } @ff; my @flags_a = map { exists $ft{$_} ? () : $_ } @ff;
$debug and print "Setting flags(@flags_a) ffrom($flags_f) fto($flags_t) on msg #$t_msg in $t_fold\n"; $debug and print "Setting flags(@flags_a) ffrom($flags_f) fto($flags_t) on msg #$h2_msg in $h2_fold\n";
# This adds or changes flags but no flag are removed with this # This adds or changes flags but no flag are removed with this
if (!$dry and @flags_a and !$to->store($t_msg, "+FLAGS.SILENT (@flags_a)") ) { if (!$dry and @flags_a and !$imap2->store($h2_msg, "+FLAGS.SILENT (@flags_a)") ) {
warn "Could not add flags '@flags_a' flagf '$flags_f'", warn "Could not add flags '@flags_a' flagf '$flags_f'",
" flagt '$flags_t' on msg #$t_msg in $t_fold: ", " flagt '$flags_t' on msg #$h2_msg in $h2_fold: ",
$to->LastError, "\n"; $imap2->LastError, "\n";
#$error++; #$error++;
} }
last FOLDER if $to->IsUnconnected(); last FOLDER if $imap2->IsUnconnected();
$debug and do { $debug and do {
my @flags_t = @{ $to->flags($t_msg) || [] }; my @flags_t = @{ $imap2->flags($h2_msg) || [] };
last FOLDER if $to->IsUnconnected(); last FOLDER if $imap2->IsUnconnected();
print "flags from: $flags_f\n", print "flags from: $flags_f\n",
"flags to : @flags_t\n"; "flags to : @flags_t\n";
print "Looking dates\n"; print "Looking dates\n";
#my $d_f = $from->internaldate($f_msg); #my $d_f = $imap1->internaldate($h1_msg);
#my $d_t = $to->internaldate($t_msg); #my $d_t = $imap2->internaldate($h2_msg);
my $d_f = $f_hash{$m_id}{'D'}; my $d_f = $h1_hash{$m_id}{'D'};
my $d_t = $t_hash{$m_id}{'D'}; my $d_t = $h2_hash{$m_id}{'D'};
print print
"idate from: $d_f\n", "idate from: $d_f\n",
"idate to : $d_t\n"; "idate to : $d_t\n";
@ -1780,41 +1780,41 @@ FOLDER: foreach my $f_fold (@f_folders) {
# print "!!! Dates differ !!!\n"; # print "!!! Dates differ !!!\n";
#} #}
}; };
unless (($f_size == $t_size) or $skipsize) { unless (($h1_size == $h2_size) or $skipsize) {
# Bad size # Bad size
print print
"Message $m_id SZ_BAD f:$f_msg:$f_size t:$t_msg:$t_size\n"; "Message $m_id SZ_BAD f:$h1_msg:$h1_size t:$h2_msg:$h2_size\n";
# delete in to and recopy ? # delete in to and recopy ?
# NO recopy CODE HERE. to be written if needed. # NO recopy CODE HERE. to be written if needed.
$error++; $error++;
if ($opt_G){ if ($opt_G){
print "Deleting msg f:#$t_msg in folder $t_fold\n"; print "Deleting msg f:#$h2_msg in folder $h2_fold\n";
$to->delete_message($t_msg) unless ($dry); $imap2->delete_message($h2_msg) unless ($dry);
last FOLDER if $to->IsUnconnected(); last FOLDER if $imap2->IsUnconnected();
} }
} }
else { else {
# Good # Good
$debug and print $debug and print
"Message $m_id SZ_GOOD f:$f_msg:$f_size t:$t_msg:$t_size\n"; "Message $m_id SZ_GOOD f:$h1_msg:$h1_size t:$h2_msg:$h2_size\n";
if($delete) { if($delete) {
print "Deleting msg #$f_msg in folder $f_fold\n"; print "Deleting msg #$h1_msg in folder $h1_fold\n";
unless($dry) { unless($dry) {
$from->delete_message($f_msg); $imap1->delete_message($h1_msg);
last FOLDER if $from->IsUnconnected(); last FOLDER if $imap1->IsUnconnected();
$from->expunge() if ($expunge); $imap1->expunge() if ($expunge);
last FOLDER if $from->IsUnconnected(); last FOLDER if $imap1->IsUnconnected();
} }
} }
} }
} }
if ($expunge1){ if ($expunge1){
print "Expunging source folder $f_fold\n"; print "Expunging source folder $h1_fold\n";
unless($dry) { $from->expunge() }; unless($dry) { $imap1->expunge() };
} }
if ($expunge2){ if ($expunge2){
print "Expunging target folder $t_fold\n"; print "Expunging target folder $h2_fold\n";
unless($dry) { $to->expunge() }; unless($dry) { $imap2->expunge() };
} }
print "Time: ", timenext(), " s\n"; print "Time: ", timenext(), " s\n";
@ -1825,7 +1825,7 @@ print "++++ End looping on each folder ++++\n";
# FOLDER loop is exited any time a connection is lost be sure to log it! # FOLDER loop is exited any time a connection is lost be sure to log it!
# Example: # Example:
# lost_connection($from,"(from) host1 [$host1]"); # lost_connection($imap1,"host1 [$host1]");
# #
# can be tested with a "killall /usr/bin/imapd" (or equivalent) in command line. # can be tested with a "killall /usr/bin/imapd" (or equivalent) in command line.
# #
@ -1860,8 +1860,8 @@ sub lost_connection {
} }
} }
$from->logout() unless (lost_connection($from,"(from) host1 [$host1]")); $imap1->logout() unless (lost_connection($imap1,"host1 [$host1]"));
$to->logout() unless (lost_connection($to,"(to) host2 [$host2]")); $imap2->logout() unless (lost_connection($imap2,"host2 [$host2]"));
$timeend = time(); $timeend = time();