mirror of
https://github.com/imapsync/imapsync.git
synced 2024-11-17 08:12:48 +01:00
350 lines
11 KiB
Diff
350 lines
11 KiB
Diff
--- imapsync.ORIG 2009-03-30 12:34:43.562500000 -0400
|
|
+++ imapsync 2009-03-30 12:32:59.890625000 -0400
|
|
@@ -70,7 +73,7 @@
|
|
[--minage <int>]
|
|
[--skipheader <regex>]
|
|
[--useheader <string>] [--useheader <string>]
|
|
- [--skipsize]
|
|
+ [--skipsize] [--allowsizemismatch]
|
|
[--delete] [--delete2]
|
|
[--expunge] [--expunge1] [--expunge2]
|
|
[--subscribed] [--subscribe]
|
|
@@ -454,7 +457,7 @@
|
|
$fastio1, $fastio2,
|
|
$maxsize, $maxage, $minage,
|
|
$skipheader, @useheader,
|
|
- $skipsize, $foldersizes, $buffersize,
|
|
+ $skipsize, $allowsizemismatch, $foldersizes, $buffersize,
|
|
$delete, $delete2,
|
|
$expunge, $expunge1, $expunge2, $dry,
|
|
$justfoldersizes,
|
|
@@ -795,20 +798,16 @@
|
|
$imap->Authuser($authuser);
|
|
$imap->Password($password);
|
|
unless ($imap->login()) {
|
|
- print "Error login: [$host] with user [$user] auth [$authmech]: $@\n";
|
|
my $info = "Error login: [$host] with user [$user] auth";
|
|
my $einfo = $imap->LastError || @{$imap->History}[-1];
|
|
chomp($einfo);
|
|
my $error = "$info [$authmech]: $einfo\n";
|
|
print $error; # note: duplicating error on stdout/stderr
|
|
- die $error if ($authmech eq 'LOGIN' or $imap->IsUnconnected() or
|
|
-$authuser);
|
|
- die if ($authmech eq 'LOGIN');
|
|
- die if $imap->IsUnconnected();
|
|
+ die $error if ($authmech eq 'LOGIN' or $imap->IsUnconnected() or $authuser);
|
|
print "Trying LOGIN Auth mechanism on [$host] with user [$user]\n";
|
|
$imap->Authmechanism("");
|
|
$imap->login() or
|
|
- die "Error login: [$host] with user [$user] auth [LOGIN]: $@";
|
|
+ die "$info [LOGIN]: ", $imap->LastError, "\n";
|
|
}
|
|
print "Success login on [$host] with user [$user] auth [$authmech]\n";
|
|
return($imap);
|
|
@@ -1294,8 +1293,8 @@
|
|
$t_fold = to_folder_name($f_fold);
|
|
print "To Folder [$t_fold]\n";
|
|
|
|
- last FOLDER if (lost_connection($from,"(from) host1 [$host1]"));
|
|
- last FOLDER if (lost_connection($to,"(to) host2 [$host2]"));
|
|
+ last FOLDER if $from->IsUnconnected();
|
|
+ last FOLDER if $to->IsUnconnected();
|
|
|
|
unless ($from->select($f_fold)) {
|
|
warn
|
|
@@ -1343,8 +1342,8 @@
|
|
|
|
next FOLDER if ($justfolders);
|
|
|
|
- last FOLDER if (lost_connection($from,"(from) host1 [$host1]"));
|
|
- last FOLDER if (lost_connection($to,"(to) host2 [$host2]"));
|
|
+ last FOLDER if $from->IsUnconnected();
|
|
+ last FOLDER if $to->IsUnconnected();
|
|
|
|
my @f_msgs = select_msgs($from);
|
|
|
|
@@ -1361,33 +1360,40 @@
|
|
my %t_hash = ();
|
|
|
|
print "++++ From [$f_fold] Parse 1 ++++\n";
|
|
- last FOLDER if (lost_connection($from,"(from) host1 [$host1]"));
|
|
- last FOLDER if (lost_connection($to,"(to) host2 [$host2]"));
|
|
+ last FOLDER if $from->IsUnconnected();
|
|
+ last FOLDER if $to->IsUnconnected();
|
|
|
|
my $f_heads = $from->parse_headers([@f_msgs],
|
|
@useheader)if (@f_msgs) ;
|
|
$debug and print "Time headers: ", timenext(), " s\n";
|
|
+ last FOLDER if $from->IsUnconnected();
|
|
my $f_fir = $from->fetch_hash("FLAGS",
|
|
"INTERNALDATE",
|
|
"RFC822.SIZE") if (@f_msgs);
|
|
$debug and print "Time fir: ", timenext(), " s\n";
|
|
-
|
|
+ last FOLDER if $from->IsUnconnected();
|
|
+
|
|
foreach my $m (@f_msgs) {
|
|
- parse_header_msg1($from, $m, $f_heads, $f_fir, "F", \%f_hash);
|
|
+ unless (parse_header_msg1($from, $m, $f_heads, $f_fir, "F", \%f_hash)) {
|
|
+ my $f_size = $f_fir->{$m}->{"RFC822.SIZE"} || 0;
|
|
+ print "+ Skipping msg #$m:$f_size in folder $f_fold (no header so we ignore this message)\n";
|
|
+ $mess_size_total_skipped += $f_size;
|
|
+ $mess_skipped += 1;
|
|
+ }
|
|
}
|
|
$debug and print "Time headers: ", timenext(), " s\n";
|
|
|
|
print "++++ To [$t_fold] Parse 1 ++++\n";
|
|
- last FOLDER if (lost_connection($from,"(from) host1 [$host1]"));
|
|
- last FOLDER if (lost_connection($to,"(to) host2 [$host2]"));
|
|
|
|
my $t_heads = $to->parse_headers([@t_msgs],
|
|
@useheader) if (@t_msgs);
|
|
$debug and print "Time headers: ", timenext(), " s\n";
|
|
+ last FOLDER if $to->IsUnconnected();
|
|
my $t_fir = $to->fetch_hash("FLAGS",
|
|
"INTERNALDATE",
|
|
"RFC822.SIZE") if (@t_msgs);
|
|
$debug and print "Time fir: ", timenext(), " s\n";
|
|
+ last FOLDER if $to->IsUnconnected();
|
|
foreach my $m (@t_msgs) {
|
|
parse_header_msg1($to, $m, $t_heads, $t_fir, "T", \%t_hash);
|
|
}
|
|
@@ -1411,7 +1417,10 @@
|
|
unless (exists($f_hash{$m_id})) {
|
|
my $t_msg = $t_hash{$m_id}{'m'};
|
|
print "deleting message $m_id $t_msg\n";
|
|
- $to->delete_message($t_msg) unless ($dry);
|
|
+ unless ($dry) {
|
|
+ $to->delete_message($t_msg);
|
|
+ last FOLDER if $to->IsUnconnected();
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
@@ -1432,10 +1441,18 @@
|
|
print "+ NO msg #$f_msg [$m_id] in $t_fold\n";
|
|
# copy
|
|
print "+ Copying msg #$f_msg:$f_size to folder $t_fold\n";
|
|
- last FOLDER if (lost_connection($from,"(from) host1 [$host1]"));
|
|
- last FOLDER if (lost_connection($to,"(to) host2 [$host2]"));
|
|
+ last FOLDER if $from->IsUnconnected();
|
|
+ last FOLDER if $to->IsUnconnected();
|
|
my $string;
|
|
$string = $from->message_string($f_msg);
|
|
+ unless (defined($string)) {
|
|
+ warn
|
|
+ "Could not fetch message #$f_msg from $f_fold ",
|
|
+ $from->LastError, "\n";
|
|
+ $error++;
|
|
+ $mess_size_total_error += $f_size;
|
|
+ next MESS;
|
|
+ }
|
|
#print "AAAmessage_string[$string]ZZZ\n";
|
|
#my $message_file = "tmp_imapsync_$$";
|
|
#$from->select($f_fold);
|
|
@@ -1514,8 +1531,8 @@
|
|
|
|
my $new_id;
|
|
print "flags from: [$flags_f][$d]\n";
|
|
- last FOLDER if (lost_connection($from,"(from) host1 [$host1]"));
|
|
- last FOLDER if (lost_connection($to,"(to) host2 [$host2]"));
|
|
+ last FOLDER if $from->IsUnconnected();
|
|
+ last FOLDER if $to->IsUnconnected();
|
|
unless ($dry) {
|
|
|
|
if ($OSNAME eq "MSWin32") {
|
|
@@ -1528,6 +1545,7 @@
|
|
$new_id = $to->append_string($t_fold,$string, $flags_f, $d);
|
|
}
|
|
unless($new_id){
|
|
+ no warnings 'uninitialized';
|
|
warn "Couldn't append msg #$f_msg (Subject:[".
|
|
$from->subject($f_msg)."]) to folder $t_fold: ",
|
|
$to->LastError, "\n";
|
|
@@ -1544,8 +1562,12 @@
|
|
$mess_trans += 1;
|
|
if($delete) {
|
|
print "Deleting msg #$f_msg in folder $f_fold\n";
|
|
- $from->delete_message($f_msg) unless ($dry);
|
|
- $from->expunge() if ($expunge and not $dry);
|
|
+ unless($dry) {
|
|
+ $from->delete_message($f_msg);
|
|
+ last FOLDER if $from->IsUnconnected();
|
|
+ $from->expunge() if ($expunge);
|
|
+ last FOLDER if $from->IsUnconnected();
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
@@ -1568,8 +1590,8 @@
|
|
|
|
|
|
$debug and print "Setting flags\n";
|
|
- last FOLDER if (lost_connection($from,"(from) host1 [$host1]"));
|
|
- last FOLDER if (lost_connection($to,"(to) host2 [$host2]"));
|
|
+ last FOLDER if $from->IsUnconnected();
|
|
+ last FOLDER if $to->IsUnconnected();
|
|
|
|
|
|
my (@flags_f,@flags_t);
|
|
@@ -1585,8 +1607,11 @@
|
|
$to->store($t_msg,
|
|
"+FLAGS.SILENT (" . $flags_f . ")"
|
|
) unless ($dry);
|
|
+ last FOLDER if $to->IsUnconnected();
|
|
|
|
my $flags_t_rv = $to->flags($t_msg);
|
|
+ last FOLDER if $to->IsUnconnected();
|
|
+
|
|
@flags_t = @{$flags_t_rv} if ref($flags_t_rv);
|
|
my $flags_t = join(" ", @flags_t);
|
|
$debug and print
|
|
@@ -1618,6 +1643,7 @@
|
|
if ($opt_G){
|
|
print "Deleting msg f:#$t_msg in folder $t_fold\n";
|
|
$to->delete_message($t_msg) unless ($dry);
|
|
+ last FOLDER if $to->IsUnconnected();
|
|
}
|
|
}
|
|
else {
|
|
@@ -1626,8 +1652,12 @@
|
|
"Message $m_id SZ_GOOD f:$f_msg:$f_size t:$t_msg:$t_size\n";
|
|
if($delete) {
|
|
print "Deleting msg #$f_msg in folder $f_fold\n";
|
|
- $from->delete_message($f_msg) unless ($dry);
|
|
- $from->expunge() if ($expunge and not $dry);
|
|
+ unless($dry) {
|
|
+ $from->delete_message($f_msg);
|
|
+ last FOLDER if $from->IsUnconnected();
|
|
+ $from->expunge() if ($expunge);
|
|
+ last FOLDER if $from->IsUnconnected();
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
@@ -1656,15 +1686,25 @@
|
|
my($imap, $error_message) = @_;
|
|
if ( $imap->IsUnconnected() ) {
|
|
$error++;
|
|
- warn("error: lost connection $error_message\n");
|
|
+ my $einfo = $imap->LastError || @{$imap->History}[-1] || "";
|
|
+ my $sz = 64;
|
|
+ # if einfo is long try reduce to a more reasonable size
|
|
+ if ( ! $debug and length($einfo) > $sz*2 ) {
|
|
+ my $beg = substr($einfo, 0, $sz);
|
|
+ my $end = substr($einfo, -$sz, $sz);
|
|
+ $einfo = $beg . "..." . $end;
|
|
+ }
|
|
+ chomp($einfo);
|
|
+ $einfo = ": $einfo" if $einfo;
|
|
+ warn("error: lost connection $error_message $einfo\n");
|
|
return(1);
|
|
}else{
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
-$from->logout() unless $from->isUnconnected();
|
|
-$to->logout() unless $to->isUnconnected();
|
|
+$from->logout() unless (lost_connection($from,"(from) host1 [$host1]"));
|
|
+$to->logout() unless (lost_connection($to,"(to) host2 [$host2]"));
|
|
|
|
$timeend = time();
|
|
|
|
@@ -1789,6 +1829,7 @@
|
|
"skipheader=s" => \$skipheader,
|
|
"useheader=s" => \@useheader,
|
|
"skipsize!" => \$skipsize,
|
|
+ "allowsizemismatch!" => \$allowsizemismatch,
|
|
"fastio1!" => \$fastio1,
|
|
"fastio2!" => \$fastio2,
|
|
"ssl1!" => \$ssl1,
|
|
@@ -2037,6 +2078,9 @@
|
|
Ex: Message-ID or Subject or Date.
|
|
--useheader <string> and this one, etc.
|
|
--skipsize : Don't take message size into account.
|
|
+--allowsizemismatch : allow RFC822.SIZE != fetched msg size
|
|
+ consider --skipsize to avoid duplicate messages
|
|
+ when running syncs more than one time per mailbox
|
|
--dry : do nothing, just print what would be done.
|
|
--subscribed : transfers subscribed folders.
|
|
--subscribe : subscribe to the folders transferred on the
|
|
@@ -2648,20 +2692,8 @@
|
|
return $self->{SSL};
|
|
};
|
|
|
|
-{
|
|
-no warnings 'once';
|
|
-*Mail::IMAPClient::Authuser = sub {
|
|
- my $self = shift;
|
|
-
|
|
- if (@_) { $self->{AUTHUSER} = shift }
|
|
- return $self->{AUTHUSER};
|
|
-};
|
|
-}
|
|
-
|
|
-# End of sub override_imapclient (yes, very bad indentation)
|
|
}
|
|
|
|
-# *Mail::IMAPClient::connect = sub {
|
|
sub myconnect {
|
|
my $self = shift;
|
|
|
|
@@ -2691,20 +2723,22 @@
|
|
$self->Socket($sock);
|
|
if ( $Mail::IMAPClient::VERSION =~ /^2/ ) {
|
|
return undef unless myconnect_v2($self);
|
|
- }
|
|
- if ($self->User and $self->Password) {
|
|
- return $self->login ;
|
|
- }
|
|
- else {
|
|
- return $self;
|
|
- }
|
|
+ }
|
|
+ else {
|
|
+ $self->Ignoresizeerrors($allowsizemismatch);
|
|
+ }
|
|
+ if ($self->User and $self->Password) {
|
|
+ return $self->login ;
|
|
+ }
|
|
+ else {
|
|
+ return $self;
|
|
+ }
|
|
}
|
|
|
|
|
|
sub myconnect_v2 {
|
|
- my $self = shift;
|
|
+ my $self = shift;
|
|
$self->State(Connected);
|
|
- # $sock->autoflush(1);
|
|
$self->Socket->autoflush(1);
|
|
my ($code, $output);
|
|
$output = "";
|
|
@@ -2719,9 +2753,23 @@
|
|
}
|
|
|
|
}
|
|
+
|
|
+ if ($code =~ /BYE|NO /) {
|
|
+ $self->State(Unconnected);
|
|
+ return undef ;
|
|
+ }
|
|
return $self;
|
|
}
|
|
|
|
+# HACK: Mail::IMAPClient 2.2.9 does not have Authuser, but 3.x does
|
|
+# - avoid warning: "Mail::IMAPClient::Authuser" used only once w/2.x too
|
|
+$Mail::IMAPClient::Authuser = $Mail::IMAPClient::Authuser = sub {
|
|
+ my $self = shift;
|
|
+
|
|
+ if (@_) { $self->{AUTHUSER} = shift }
|
|
+ return $self->{AUTHUSER};
|
|
+} if ( $Mail::IMAPClient::VERSION =~ /^2/ );
|
|
+
|
|
package Mail::IMAPClient;
|
|
|
|
|