mirror of
https://github.com/imapsync/imapsync.git
synced 2025-08-02 15:11:49 +02:00
1.239
This commit is contained in:
parent
6576e43299
commit
0d91a1a20f
80 changed files with 31457 additions and 28691 deletions
350
imapsync
350
imapsync
|
@ -9,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.233 $
|
||||
$Revision: 1.239 $
|
||||
|
||||
=head1 INSTALL
|
||||
|
||||
|
@ -211,6 +211,12 @@ No known serious bug. Report any bug to the author.
|
|||
Before reporting bugs, read the FAQ, this README and the
|
||||
TODO files.
|
||||
|
||||
Don't write imapsync in uppercase in the email title, I'll
|
||||
know you run windows.
|
||||
|
||||
Make a good title, not just "imapsync" or "problem",
|
||||
a good title is made of keywords summary, not too long (one visible line).
|
||||
|
||||
In your report, please include:
|
||||
|
||||
- imapsync version.
|
||||
|
@ -242,12 +248,13 @@ Failure stories reported with the following 4 imap servers :
|
|||
- dkimap4 2.39
|
||||
- Imail 7.04 (maybe).
|
||||
|
||||
Success stories reported with the following 34 imap servers
|
||||
Success stories reported with the following 35 imap servers
|
||||
(softwares names are in alphabetic order) :
|
||||
|
||||
- Archiveopteryx 2.03, 2.04 (OSL 3.0) http://www.archiveopteryx.org/
|
||||
- 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, 3.0.8 (GPL)
|
||||
- Courier IMAP 1.5.1, 2.2.0, 2.1.1, 2.2.1, 3.0.8, 3.0.3, 4.1.1 (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
|
||||
|
@ -278,7 +285,7 @@ Success stories reported with the following 34 imap servers
|
|||
- OpenMail IMAP server B.07.00.k0 (Samsung Contact ?)
|
||||
- OpenWave
|
||||
- Qualcomm Worldmail (NT)
|
||||
- Rockliffe Mailsite 5.3.11
|
||||
- Rockliffe Mailsite 5.3.11, 4.5.6
|
||||
- Samsung Contact IMAP server 8.5.0
|
||||
- Scalix v10.1, 10.0.1.3, 11.0.0.431
|
||||
- SmarterMail
|
||||
|
@ -290,7 +297,7 @@ Success stories reported with the following 34 imap servers
|
|||
(http://www.washington.edu/imap/)
|
||||
- UW - QMail v2.1
|
||||
- Imap part of TCP/IP suite of VMS 7.3.2
|
||||
- Zimbra-IMAP 3.0.1 GA 160, 3.1.0 Build 279, 4.0.5, 4.5.2, 5.5.
|
||||
- Zimbra-IMAP 3.0.1 GA 160, 3.1.0 Build 279, 4.0.5, 4.5.2, 4.5.6, 5.5.
|
||||
|
||||
Please report to the author any success or bad story with
|
||||
imapsync and don't forget to mention the IMAP server
|
||||
|
@ -373,11 +380,13 @@ Entries for imapsync:
|
|||
imapcopy : http://home.arcor.de/armin.diehl/imapcopy/imapcopy.html
|
||||
migrationtool : http://sourceforge.net/projects/migrationtool/
|
||||
imapmigrate : http://sourceforge.net/projects/cyrus-utils/
|
||||
wonko_imapsync: http://wonko.com/article/554
|
||||
pop2imap : http://www.linux-france.org/prj/pop2imap/
|
||||
|
||||
|
||||
Feedback (good or bad) will be always welcome.
|
||||
|
||||
$Id: imapsync,v 1.233 2007/10/30 03:20:53 gilles Exp gilles $
|
||||
$Id: imapsync,v 1.239 2007/12/29 02:44:10 gilles Exp $
|
||||
|
||||
|
||||
|
||||
|
@ -396,6 +405,9 @@ use English;
|
|||
use POSIX qw(uname);
|
||||
use Fcntl;
|
||||
|
||||
#use Test::Simple tests => 1;
|
||||
use Test::More 'no_plan';
|
||||
|
||||
eval { require 'usr/include/sysexits.ph' };
|
||||
|
||||
|
||||
|
@ -431,19 +443,20 @@ my(
|
|||
$authuser1, $authuser2,
|
||||
$authmech1, $authmech2,
|
||||
$split1, $split2,
|
||||
$tests, $test_builder,
|
||||
);
|
||||
|
||||
use vars qw ($opt_G); # missing code for this will be option.
|
||||
|
||||
|
||||
$rcs = ' $Id: imapsync,v 1.233 2007/10/30 03:20:53 gilles Exp gilles $ ';
|
||||
$rcs = ' $Id: imapsync,v 1.239 2007/12/29 02:44:10 gilles Exp $ ';
|
||||
$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 "imapsync needs perl lib Mail::IMAPClient release 2.2.9 exactly, future imapsync release may suppoort 3.0.x, but sorry not now\n";
|
||||
|
||||
|
||||
$mess_size_total_trans = 0;
|
||||
|
@ -453,18 +466,14 @@ $mess_trans = $mess_skipped = $mess_skipped_dry = 0;
|
|||
|
||||
|
||||
sub check_lib_version {
|
||||
# I know this is ugly, I should write a sort function
|
||||
if ($VERSION_IMAPClient =~ m/(\d+)\.(\d+)\.(\d+)/) {
|
||||
$debug and print "VERSION_IMAPClient $1 $2 $3\n";
|
||||
my($major,$minor,$sub) = ($1, $2, $3);
|
||||
#my($major,$minor,$sub) = ($1, $2, $3);
|
||||
|
||||
return(1) if($major >=3);
|
||||
return(0) if($major <=1);
|
||||
return(1) if($minor >=3);
|
||||
return(0) if($minor <=1);
|
||||
return(1) if($sub >=8);
|
||||
return(0) if($sub <=7);
|
||||
}else{
|
||||
return(1) if($VERSION_IMAPClient eq '2.2.9');
|
||||
|
||||
}
|
||||
else{
|
||||
return 0; # don't match regex => bad
|
||||
}
|
||||
}
|
||||
|
@ -473,8 +482,8 @@ $error=0;
|
|||
|
||||
my $banner = join("",
|
||||
'$RCSfile: imapsync,v $ ',
|
||||
'$Revision: 1.233 $ ',
|
||||
'$Date: 2007/10/30 03:20:53 $ ',
|
||||
'$Revision: 1.239 $ ',
|
||||
'$Date: 2007/12/29 02:44:10 $ ',
|
||||
"\n",localhost_info(),
|
||||
" and the module Mail::IMAPClient version used here is ",
|
||||
$VERSION_IMAPClient,"\n",
|
||||
|
@ -552,7 +561,8 @@ $user2 || missing_option("--user2");
|
|||
if(defined($authmd5) and not($authmd5)) {
|
||||
$authmech1 ||= 'LOGIN';
|
||||
$authmech2 ||= 'LOGIN';
|
||||
}else{
|
||||
}
|
||||
else{
|
||||
$authmech1 ||= $authuser1 ? 'PLAIN' : 'CRAM-MD5';
|
||||
$authmech2 ||= $authuser2 ? 'PLAIN' : 'CRAM-MD5';
|
||||
}
|
||||
|
@ -641,7 +651,8 @@ sub login_imap {
|
|||
Socket => $socssl,
|
||||
Server => $host,
|
||||
);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$imap = Mail::IMAPClient->new();
|
||||
}
|
||||
$imap->Clear(20);
|
||||
|
@ -656,7 +667,8 @@ sub login_imap {
|
|||
|
||||
if ($ssl) {
|
||||
$imap->State(Mail::IMAPClient::Connected);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$imap->connect2()
|
||||
or die "Can not open imap connection on [$host] with user [$user] : $@\n";
|
||||
}
|
||||
|
@ -667,7 +679,8 @@ sub login_imap {
|
|||
) {
|
||||
printf("Host %s says it has CAPABILITY for AUTHENTICATE %s\n",
|
||||
$imap->Server, $authmech);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
printf("Host %s says it has NO CAPABILITY for AUTHENTICATE %s\n",
|
||||
$imap->Server, $authmech);
|
||||
if ($authmech eq 'PLAIN') {
|
||||
|
@ -727,43 +740,191 @@ print "To state Authenticated\n";
|
|||
$split1 and $from->Split($split1);
|
||||
$split2 and $to->Split($split2);
|
||||
|
||||
#
|
||||
# Folder stuff
|
||||
#
|
||||
|
||||
my (@f_folders, %requested_folder, @t_folders, %subscribed_folder, %t_folders);
|
||||
|
||||
sub tests_folder_routines {
|
||||
ok( !give_requested_folders() ,"no requested folders" );
|
||||
ok( !is_requested_folder('folder_foo') );
|
||||
ok( add_to_requested_folders('folder_foo') );
|
||||
ok( is_requested_folder('folder_foo') );
|
||||
ok( !is_requested_folder('folder_NO_EXIST') );
|
||||
ok( !remove_from_requested_folders('folder_foo'), "removed folder_foo");
|
||||
ok( !is_requested_folder('folder_foo') );
|
||||
my @f;
|
||||
ok( @f = add_to_requested_folders('folder_bar', 'folder_toto'), "add result: @f");
|
||||
ok( is_requested_folder('folder_bar') );
|
||||
ok( is_requested_folder('folder_toto') );
|
||||
ok( remove_from_requested_folders('folder_toto') );
|
||||
ok( !is_requested_folder('folder_toto') );
|
||||
ok( init_requested_folders() , 'empty requested folders');
|
||||
ok( !give_requested_folders() , 'no requested folders' );
|
||||
}
|
||||
|
||||
sub give_requested_folders {
|
||||
return(keys(%requested_folder));
|
||||
}
|
||||
|
||||
sub init_requested_folders {
|
||||
|
||||
%requested_folder = ();
|
||||
return(1);
|
||||
|
||||
}
|
||||
|
||||
sub is_requested_folder {
|
||||
my ( $folder ) = @_;
|
||||
|
||||
defined( $requested_folder{ $folder } );
|
||||
}
|
||||
|
||||
|
||||
sub add_to_requested_folders {
|
||||
my @wanted_folders = @_;
|
||||
|
||||
foreach my $folder ( @wanted_folders ) {
|
||||
++$requested_folder{ $folder };
|
||||
}
|
||||
return( keys( %requested_folder ) );
|
||||
}
|
||||
|
||||
sub remove_from_requested_folders {
|
||||
my @wanted_folders = @_;
|
||||
|
||||
foreach my $folder (@wanted_folders) {
|
||||
delete $requested_folder{$folder};
|
||||
}
|
||||
return( keys(%requested_folder) );
|
||||
}
|
||||
|
||||
my (@f_folders, @t_folders, %fs_folders, %t_folders);
|
||||
|
||||
# Make a hash of subscribed folders in source server.
|
||||
map { $fs_folders{$_}=1 } $from->subscribed();
|
||||
map { $subscribed_folder{$_} = 1 } $from->subscribed();
|
||||
|
||||
|
||||
my @all_source_folders = sort $from->folders();
|
||||
|
||||
if (scalar(@folder) or $subscribed or scalar(@folderrec)) {
|
||||
# folders given by option --folder
|
||||
push(@f_folders, @folder) if scalar(@folder);
|
||||
# option --subscribed
|
||||
push(@f_folders, sort keys (%fs_folders)) if ($subscribed);
|
||||
if (scalar(@folder)) {
|
||||
add_to_requested_folders(@folder);
|
||||
}
|
||||
|
||||
# option --subscribed
|
||||
if ($subscribed) {
|
||||
add_to_requested_folders(keys (%subscribed_folder));
|
||||
}
|
||||
|
||||
# option --folderrec
|
||||
if (scalar(@folderrec)) {
|
||||
foreach my $folderrec (@folderrec) {
|
||||
push(@f_folders, $from->folders($folderrec));
|
||||
add_to_requested_folders($from->folders($folderrec));
|
||||
}
|
||||
}
|
||||
@f_folders = sort @f_folders;
|
||||
}else {
|
||||
# no folder/subscribed/folderrec options => all folders
|
||||
@f_folders = sort $from->folders();
|
||||
}
|
||||
else {
|
||||
|
||||
# no include, no folder/subscribed/folderrec options => all folders
|
||||
if (not scalar(@include)) {
|
||||
add_to_requested_folders(@all_source_folders);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# consider (optional) includes and excludes
|
||||
if (scalar(@include)) {
|
||||
my @f_folders_inc;
|
||||
foreach my $include (@include) {
|
||||
push(@f_folders_inc, grep /$include/, @f_folders);
|
||||
print "Including folders matching pattern '$include'\n";
|
||||
my @included_folders = grep /$include/, @all_source_folders;
|
||||
add_to_requested_folders(@included_folders);
|
||||
print "Including folders matching pattern '$include': @included_folders\n";
|
||||
}
|
||||
push(@f_folders, sort @f_folders_inc);
|
||||
}
|
||||
|
||||
foreach my $exclude (@exclude) {
|
||||
@f_folders = grep !/$exclude/,@f_folders;
|
||||
print "Excluding folders matching pattern '$exclude'\n";
|
||||
if (scalar(@exclude)) {
|
||||
foreach my $exclude (@exclude) {
|
||||
my @requested_folder = sort(keys(%requested_folder));
|
||||
my @excluded_folders = grep /$exclude/, @requested_folder;
|
||||
remove_to_requested_folders(@excluded_folders);
|
||||
print "Excluding folders matching pattern '$exclude': @excluded_folders\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
my @requested_folder = sort(keys(%requested_folder));
|
||||
|
||||
@f_folders = @requested_folder;
|
||||
|
||||
sub compare_lists {
|
||||
my ($list_1_ref, $list_2_ref) = @_;
|
||||
|
||||
return(-1) if ((not defined($list_1_ref)) and defined($list_2_ref));
|
||||
return(0) if (! $list_1_ref); # end if no list
|
||||
return(1) if (! $list_2_ref); # end if only one list
|
||||
|
||||
if (not ref($list_1_ref)) {$list_1_ref = [$list_1_ref]};
|
||||
if (not ref($list_2_ref)) {$list_2_ref = [$list_2_ref]};
|
||||
|
||||
|
||||
my $last_used_indice = 0;
|
||||
ELEMENT:
|
||||
foreach my $indice ( 0 .. $#$list_1_ref ) {
|
||||
$last_used_indice = $indice;
|
||||
|
||||
# End of list_2
|
||||
return 1 if ($indice > $#$list_2_ref);
|
||||
|
||||
my $element_list_1 = $list_1_ref->[$indice];
|
||||
my $element_list_2 = $list_2_ref->[$indice];
|
||||
my $balance = $element_list_1 cmp $element_list_2 ;
|
||||
next ELEMENT if ($balance == 0) ;
|
||||
return $balance;
|
||||
}
|
||||
# each element equal until last indice of list_1
|
||||
return -1 if ($last_used_indice < $#$list_2_ref);
|
||||
|
||||
# same size, each element equal
|
||||
return 0
|
||||
}
|
||||
|
||||
sub tests_compare_lists {
|
||||
|
||||
|
||||
my $empty_list_ref = [];
|
||||
|
||||
ok( 0 == compare_lists() , 'compare_lists, no args');
|
||||
ok( 0 == compare_lists(undef) , 'compare_lists, undef = nothing');
|
||||
ok( 0 == compare_lists(undef, undef) , 'compare_lists, undef = undef');
|
||||
ok(-1 == compare_lists(undef , []) , 'compare_lists, undef < []');
|
||||
ok(+1 == compare_lists([]) , 'compare_lists, [] > nothing');
|
||||
ok(+1 == compare_lists([], undef) , 'compare_lists, [] > undef');
|
||||
ok( 0 == compare_lists([] , []) , 'compare_lists, [] = []');
|
||||
|
||||
ok( 0 == compare_lists([1], 1 ) , "compare_lists, [1] = 1 ") ;
|
||||
ok( 0 == compare_lists( 1 , [1]) , "compare_lists, 1 = [1]") ;
|
||||
ok( 0 == compare_lists( 1 , 1 ) , "compare_lists, 1 = 1 ") ;
|
||||
ok(-1 == compare_lists( 1 , 2 ) , "compare_lists, 1 = 1 ") ;
|
||||
ok(+1 == compare_lists( 2 , 1 ) , "compare_lists, 1 = 1 ") ;
|
||||
|
||||
|
||||
ok( 0 == compare_lists([1,2], [1,2]) , "compare_lists, [1,2] = [1,2]") ;
|
||||
ok(-1 == compare_lists([1], [1,2]) , "compare_lists, [1] < [1,2]") ;
|
||||
ok(-1 == compare_lists([1], [1,1]) , "compare_lists, [1] < [1,1]") ;
|
||||
ok(+1 == compare_lists([1, 1], [1]) , "compare_lists, [1, 1] > [1]") ;
|
||||
ok( 0 == compare_lists([1 .. 20_000] , [1 .. 20_000])
|
||||
, "compare_lists, [1..20_000] = [1..20_000]") ;
|
||||
ok(-1 == compare_lists([1], [3]) , 'compare_lists, [1] < [3]') ;
|
||||
ok( 0 == compare_lists([2], [2]) , 'compare_lists, [0] = [2]') ;
|
||||
ok(+1 == compare_lists([3], [1]) , 'compare_lists, [3] > [1]') ;
|
||||
|
||||
ok(-1 == compare_lists(["a"], ["b"]) , 'compare_lists, ["a"] < ["b"]') ;
|
||||
ok( 0 == compare_lists(["a"], ["a"]) , 'compare_lists, ["a"] = ["a"]') ;
|
||||
ok( 0 == compare_lists(["ab"], ["ab"]) , 'compare_lists, ["ab"] = ["ab"]') ;
|
||||
ok(+1 == compare_lists(["b"], ["a"]) , 'compare_lists, ["b"] > ["a"]') ;
|
||||
ok(-1 == compare_lists(["a"], ["aa"]) , 'compare_lists, ["a"] < ["aa"]') ;
|
||||
ok(-1 == compare_lists(["a"], ["a", "a"]), 'compare_lists, ["a"] < ["a", "a"]') ;
|
||||
}
|
||||
|
||||
|
||||
|
@ -801,7 +962,8 @@ sub get_prefix {
|
|||
my $r_namespace = $imap->namespace();
|
||||
$prefix_out = $r_namespace->[0][0][0];
|
||||
return($prefix_out);
|
||||
}else{
|
||||
}
|
||||
else{
|
||||
print
|
||||
"No NAMESPACE capability in imap server ",
|
||||
$imap->Server(),"\n",
|
||||
|
@ -825,7 +987,8 @@ sub get_separator {
|
|||
if ($imap->has_capability("namespace")) {
|
||||
$sep_out = $imap->separator();
|
||||
return($sep_out);
|
||||
}else{
|
||||
}
|
||||
else{
|
||||
print
|
||||
"No NAMESPACE capability in imap server ",
|
||||
$imap->Server(),"\n",
|
||||
|
@ -870,7 +1033,8 @@ sub foldersizes {
|
|||
or warn "Could not find size of message $m: $@\n";
|
||||
$stot += $s;
|
||||
}
|
||||
}else{
|
||||
}
|
||||
else{
|
||||
my $hashref = {};
|
||||
$smess = $imap->message_count();
|
||||
unless ($smess == 0) {
|
||||
|
@ -932,7 +1096,7 @@ print
|
|||
|
||||
print
|
||||
"From subscribed folders list : ",
|
||||
map("[$_] ", sort keys(%fs_folders)), "\n"
|
||||
map("[$_] ", sort keys(%subscribed_folder)), "\n"
|
||||
if ($subscribed);
|
||||
|
||||
sub separator_invert {
|
||||
|
@ -1030,7 +1194,8 @@ FOLDER: foreach my $f_fold (@f_folders) {
|
|||
$error++;
|
||||
next FOLDER;
|
||||
}
|
||||
}else{
|
||||
}
|
||||
else{
|
||||
next FOLDER;
|
||||
}
|
||||
}
|
||||
|
@ -1051,7 +1216,7 @@ FOLDER: foreach my $f_fold (@f_folders) {
|
|||
#unless($dry) { $to->expunge() };
|
||||
}
|
||||
|
||||
if ($subscribe and exists $fs_folders{$f_fold}) {
|
||||
if ($subscribe and exists $subscribed_folder{$f_fold}) {
|
||||
print "Subscribing to folder $t_fold on destination server\n";
|
||||
unless($dry) { $to->subscribe($t_fold) };
|
||||
}
|
||||
|
@ -1198,7 +1363,8 @@ FOLDER: foreach my $f_fold (@f_folders) {
|
|||
$error++;
|
||||
$mess_size_total_error += $f_size;
|
||||
next MESS;
|
||||
}else{
|
||||
}
|
||||
else{
|
||||
# good
|
||||
# $new_id is an id if the IMAP server has the
|
||||
# UIDPLUS capability else just a ref
|
||||
|
@ -1211,12 +1377,14 @@ FOLDER: foreach my $f_fold (@f_folders) {
|
|||
$from->expunge() if ($expunge and not $dry);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
}
|
||||
else{
|
||||
$mess_skipped_dry += 1;
|
||||
}
|
||||
unlink($message_file);
|
||||
next MESS;
|
||||
}else{
|
||||
}
|
||||
else{
|
||||
$debug and print "Message id [$m_id] found in t:$t_fold\n";
|
||||
$mess_size_total_skipped += $f_size;
|
||||
$mess_skipped += 1;
|
||||
|
@ -1279,7 +1447,8 @@ FOLDER: foreach my $f_fold (@f_folders) {
|
|||
print "Deleting msg f:#$t_msg in folder $t_fold\n";
|
||||
$to->delete_message($t_msg) unless ($dry);
|
||||
}
|
||||
}else {
|
||||
}
|
||||
else {
|
||||
# Good
|
||||
$debug and print
|
||||
"Message $m_id SZ_GOOD f:$f_msg:$f_size t:$t_msg:$t_size\n";
|
||||
|
@ -1310,6 +1479,9 @@ $timediff = $timeend - $timestart;
|
|||
|
||||
stats();
|
||||
|
||||
|
||||
|
||||
|
||||
exit(1) if($error);
|
||||
|
||||
sub select_msgs {
|
||||
|
@ -1426,12 +1598,23 @@ sub get_options
|
|||
"authuser2=s" => \$authuser2,
|
||||
"split1=i" => \$split1,
|
||||
"split2=i" => \$split2,
|
||||
"tests" => \$tests,
|
||||
);
|
||||
|
||||
$debug and print "get options: [$opt_ret]\n";
|
||||
|
||||
$test_builder = Test::More->builder;
|
||||
$test_builder->no_ending(1);
|
||||
|
||||
# just the version
|
||||
print "$VERSION\n" and exit if ($version) ;
|
||||
|
||||
if ($tests) {
|
||||
$test_builder->no_ending(0);
|
||||
tests();
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
# exit with --help option or no option at all
|
||||
usage() and exit if ($help or ! $numopt) ;
|
||||
|
@ -1485,7 +1668,8 @@ sub parse_header_msg1 {
|
|||
my $key;
|
||||
if ($skipsize) {
|
||||
$key = "$m_md5";
|
||||
}else {
|
||||
}
|
||||
else {
|
||||
$key = "$m_md5:$size";
|
||||
}
|
||||
$s_hash->{"$key"}{'5'} = $m_md5;
|
||||
|
@ -1669,6 +1853,16 @@ EOF
|
|||
}
|
||||
|
||||
|
||||
sub tests {
|
||||
|
||||
SKIP: {
|
||||
skip "No test in normal run" if (not $tests);
|
||||
tests_folder_routines();
|
||||
tests_compare_lists();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
package Mail::IMAPClient;
|
||||
|
||||
|
||||
|
@ -1748,25 +1942,25 @@ sub append_file2 {
|
|||
|
||||
unless ($feedback) {
|
||||
$self->LastError("Error sending '$string' to IMAP: $!\n");
|
||||
close $fh;
|
||||
$fh->close;
|
||||
return undef;
|
||||
}
|
||||
|
||||
my ($code, $output) = ("","");
|
||||
|
||||
until ( $code ) {
|
||||
$output = $self->_read_line or close $fh, return undef;
|
||||
$output = $self->_read_line or $fh->close, return undef;
|
||||
foreach my $o (@$output) {
|
||||
$self->_record($count,$o); # $o is already an array ref
|
||||
($code) = $o->[DATA] =~ /(^\+|^\d+\sNO|^\d+\sBAD)/i;
|
||||
if ($o->[DATA] =~ /^\*\s+BYE/) {
|
||||
carp $o->[DATA] if $^W;
|
||||
$self->State(Unconnected);
|
||||
close $fh;
|
||||
$fh->close;
|
||||
return undef ;
|
||||
} elsif ( $o->[DATA]=~ /^\d+\s+(NO|BAD)/i ) {
|
||||
carp $o->[DATA] if $^W;
|
||||
close $fh;
|
||||
$fh->close;
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
@ -1782,7 +1976,7 @@ sub append_file2 {
|
|||
|
||||
unless ($feedback) {
|
||||
$self->LastError("Error sending append msg text to IMAP: $!\n");
|
||||
close $fh;
|
||||
$fh->close;
|
||||
return undef;
|
||||
}
|
||||
_debug $self, "control points to $$control\n" if ref($control) and $self->Debug;
|
||||
|
@ -1796,7 +1990,7 @@ sub append_file2 {
|
|||
|
||||
unless ($feedback) {
|
||||
$self->LastError("Error sending append msg text to IMAP: $!\n");
|
||||
close $fh;
|
||||
$fh->close;
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
@ -1804,7 +1998,7 @@ sub append_file2 {
|
|||
|
||||
unless ($feedback) {
|
||||
$self->LastError("Error sending append msg text to IMAP: $!\n");
|
||||
close $fh;
|
||||
$fh->close;
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
@ -1825,16 +2019,16 @@ sub append_file2 {
|
|||
if ($o->[DATA] =~ /^\*\s+BYE/) {
|
||||
carp $o->[DATA] if $^W;
|
||||
$self->State(Unconnected);
|
||||
close $fh;
|
||||
$fh->close;
|
||||
return undef ;
|
||||
} elsif ( $o->[DATA]=~ /^\d+\s+(NO|BAD)/i ) {
|
||||
carp $o->[DATA] if $^W;
|
||||
close $fh;
|
||||
$fh->close;
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
}
|
||||
close $fh;
|
||||
$fh->close;
|
||||
|
||||
if ($code !~ /^OK/i) {
|
||||
return undef;
|
||||
|
@ -1871,15 +2065,18 @@ sub fetch_hash2 {
|
|||
next unless $uid;
|
||||
if ( exists $hash->{$uid} ) {
|
||||
$entry = $hash->{$uid} ;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$hash->{$uid} ||= $entry;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
my($mid) = $l =~ /^\* (\d+) FETCH/i;
|
||||
next unless $mid;
|
||||
if ( exists $hash->{$mid} ) {
|
||||
$entry = $hash->{$mid} ;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$hash->{$mid} ||= $entry;
|
||||
}
|
||||
}
|
||||
|
@ -1889,7 +2086,8 @@ sub fetch_hash2 {
|
|||
$entry->{$w} = $output->[$x+1];
|
||||
$entry->{$w} =~ s/(?:\x0a?\x0d)+$//g;
|
||||
chomp $entry->{$w};
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$l =~ /\( # open paren followed by ...
|
||||
(?:.*\s)? # ...optional stuff and a space
|
||||
\Q$w\E\s # escaped fetch field<sp>
|
||||
|
@ -1933,7 +2131,7 @@ sub login2 {
|
|||
$carp =~ s/^[\S]+ ([^\x0d\x0a]*)\x0d?\x0a/$1/;
|
||||
carp $carp unless defined wantarray;
|
||||
return undef;
|
||||
}
|
||||
};
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
@ -1969,7 +2167,7 @@ sub parse_headers2 {
|
|||
".peek"
|
||||
) . "[header]" ;
|
||||
|
||||
} else {
|
||||
}else {
|
||||
$string = "$msg body" .
|
||||
# use ".peek" if Peek parameter is a) defined and true, or
|
||||
# b) undefined, but not if it's defined and untrue:
|
||||
|
@ -1992,10 +2190,12 @@ sub parse_headers2 {
|
|||
if ( my($msgid) = $header =~ /UID\s+(\d+)/ ) {
|
||||
$h = {};
|
||||
$headers->{$msgid} = $h;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$h = {};
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if ( my($msgid) = $header =~ /^\*\s+(\d+)/ ) {
|
||||
#start of new message header:
|
||||
$h = {};
|
||||
|
@ -2104,7 +2304,8 @@ sub authenticate2 {
|
|||
if ($Mail::IMAPClient::_CRAM_MD5_ERR) {
|
||||
$self->LastError($Mail::IMAPClient::_CRAM_MD5_ERR);
|
||||
carp $Mail::IMAPClient::_CRAM_MD5_ERR if $^W;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$response = \&_cram_md5_2;
|
||||
}
|
||||
}
|
||||
|
@ -2159,8 +2360,8 @@ sub connect2 {
|
|||
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)');
|
||||
my $sock = IO::Socket::INET->new;
|
||||
my $dp = 'imap(143)';
|
||||
#print "i01\n";
|
||||
my $ret = $sock->configure({
|
||||
PeerAddr => $self->Server ,
|
||||
|
@ -2206,7 +2407,8 @@ sub connect2 {
|
|||
|
||||
if ($self->User and $self->Password) {
|
||||
return $self->login ;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return $self;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue